Implement copy constructor and assignment operator.

PiperOrigin-RevId: 524941810
pull/13171/head
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent 565c8fe66e
commit 433e737c0e
  1. 3
      BUILD
  2. 1
      protos_generator/BUILD
  3. 56
      protos_generator/gen_messages.cc
  4. 1
      protos_generator/protoc-gen-upb-protos.cc
  5. 58
      protos_generator/tests/test_generated.cc

@ -421,9 +421,11 @@ cc_library(
cc_library(
name = "generated_cpp_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
hdrs = [
"upb/message/copy.h",
"upb/message/extension_internal.h",
"upb/message/internal.h",
"upb/message/message.h",
"upb/mini_table/common.h",
"upb/mini_table/enum_internal.h",
"upb/mini_table/extension_internal.h",
"upb/mini_table/field_internal.h",
@ -444,6 +446,7 @@ cc_library(
":base",
":collections_internal",
":hash",
":message_copy",
":mini_table",
":upb",
],

@ -65,6 +65,7 @@ cc_library(
],
visibility = ["//visibility:private"],
deps = [
"//:message_copy",
"//upbc:common",
"//upbc:file_layout",
"//upbc:keywords",

@ -97,8 +97,8 @@ void WriteMessageClassDeclarations(
output("} // namespace internal\n");
WriteModelPublicDeclaration(descriptor, file_exts, file_enums, output);
output("namespace internal {\n");
WriteModelProxyDeclaration(descriptor, output);
WriteModelCProxyDeclaration(descriptor, output);
WriteModelProxyDeclaration(descriptor, output);
output("} // namespace internal\n");
}
@ -151,22 +151,38 @@ void WriteModelPublicDeclaration(
using Access = internal::$0Access;
using Proxy = internal::$0Proxy;
using CProxy = internal::$0CProxy;
$0();
$0(const $0& m) = delete;
$0& operator=(const $0& m) = delete;
$0(const $0& from);
inline $0& operator=(const $3& from) {
arena_ = owned_arena_.ptr();
msg_ = ($2*)upb_Message_DeepClone(from.msg_, &$1, arena_);
return *this;
}
$0(const CProxy& from);
$0(const Proxy& from);
inline $0& operator=(const CProxy& from) {
arena_ = owned_arena_.ptr();
msg_ = ($2*)upb_Message_DeepClone(
::protos::internal::GetInternalMsg(from), &$1, arena_);
return *this;
}
$0($0&& m)
: Access(m.msg_, m.arena_),
: Access(absl::exchange(m.msg_, nullptr),
absl::exchange(m.arena_, nullptr)),
owned_arena_(std::move(m.owned_arena_)) {}
$0& operator=($0&& m) {
msg_ = m.msg_;
arena_ = m.arena_;
m.msg_ = nullptr;
m.arena_ = nullptr;
msg_ = absl::exchange(m.msg_, nullptr);
arena_ = absl::exchange(m.arena_, nullptr);
owned_arena_ = std::move(m.owned_arena_);
return *this;
}
)cc",
ClassName(descriptor));
ClassName(descriptor), ::upbc::MessageInit(descriptor->full_name()),
MessageName(descriptor), QualifiedClassName(descriptor));
WriteUsingAccessorsInHeader(descriptor, MessageClassType::kMessage, output);
WriteUsingEnumsInHeader(descriptor, file_enums, output);
@ -274,6 +290,7 @@ void WriteModelCProxyDeclaration(const protobuf::Descriptor* descriptor,
public:
$0CProxy() = delete;
$0CProxy(const $0* m) : internal::$0Access(m->msg_, nullptr) {}
$0CProxy($0Proxy m);
using $0Access::GetInternalArena;
)cc",
ClassName(descriptor), MessageName(descriptor));
@ -318,15 +335,32 @@ void WriteMessageImplementation(
arena_ = owned_arena_.ptr();
msg_ = $1_new(arena_);
}
$0::$0(const $0& from) : $0Access() {
arena_ = owned_arena_.ptr();
msg_ = ($1*)upb_Message_DeepClone(from.msg_, &$2, arena_);
}
$0::$0(const CProxy& from) : $0Access() {
arena_ = owned_arena_.ptr();
msg_ = ($1*)upb_Message_DeepClone(
::protos::internal::GetInternalMsg(from), &$2, arena_);
}
$0::$0(const Proxy& from) : $0(static_cast<const CProxy&>(from)) {}
internal::$0CProxy::$0CProxy($0Proxy m) : $0Access() {
arena_ = m.arena_;
msg_ = ($1*)::protos::internal::GetInternalMsg(m);
}
)cc",
ClassName(descriptor), MessageName(descriptor));
ClassName(descriptor), MessageName(descriptor),
::upbc::MessageInit(descriptor->full_name()),
QualifiedClassName(descriptor));
output("\n");
// Minitable
OutputIndenter i(output);
output(
R"cc(
const upb_MiniTable* $0::minitable() { return &$1; }
)cc",
ClassName(descriptor), ::upbc::MessageInit(descriptor->full_name()));
output("\n");
}
WriteAccessorsInSource(descriptor, output);

@ -134,6 +134,7 @@ void WriteHeader(const protobuf::FileDescriptor* file, Output& output) {
#include "absl/strings/string_view.h"
#include "absl/status/statusor.h"
#include "upb/message/internal.h"
#include "upb/message/copy.h"
)cc",
ToPreproc(file->name()));

@ -25,6 +25,7 @@
#include <limits>
#include <memory>
#include <utility>
#include "gtest/gtest.h"
#include "protos/protos.h"
@ -640,3 +641,60 @@ TEST(CppGeneratedCode, UniquePointer) {
auto bytes = protos::Serialize(model, arena);
EXPECT_TRUE(protos::Parse(model, bytes.value()));
}
TEST(CppGeneratedCode, Assignment) {
TestModel model;
model.set_category(5);
model.mutable_child_model_1()->set_child_str1("text in child");
TestModel model2 = model;
EXPECT_EQ(5, model2.category());
EXPECT_EQ(model2.child_model_1()->child_str1(), "text in child");
}
TEST(CppGeneratedCode, PtrAssignment) {
TestModel model;
model.mutable_child_model_1()->set_child_str1("text in child");
ChildModel1 child_from_const_ptr = *model.child_model_1();
EXPECT_EQ(child_from_const_ptr.child_str1(), "text in child");
ChildModel1 child_from_ptr = *model.mutable_child_model_1();
EXPECT_EQ(child_from_ptr.child_str1(), "text in child");
}
TEST(CppGeneratedCode, CopyConstructor) {
TestModel model;
model.set_category(6);
TestModel model2(model);
EXPECT_EQ(6, model2.category());
}
TEST(CppGeneratedCode, PtrConstructor) {
TestModel model;
model.mutable_child_model_1()->set_child_str1("text in child");
ChildModel1 child_from_ptr(*model.mutable_child_model_1());
EXPECT_EQ(child_from_ptr.child_str1(), "text in child");
ChildModel1 child_from_const_ptr(*model.child_model_1());
EXPECT_EQ(child_from_const_ptr.child_str1(), "text in child");
}
TEST(CppGeneratedCode, MutableToProxy) {
TestModel model;
::protos::Ptr<ChildModel1> child = model.mutable_child_model_1();
(void)child;
}
TEST(CppGeneratedCode, ProxyToCProxy) {
TestModel model;
::protos::Ptr<ChildModel1> child = model.mutable_child_model_1();
::protos::Ptr<const ChildModel1> child2 = child;
(void)child2;
}
bool ProxyToCProxyMethod(::protos::Ptr<const ChildModel1> child) {
return child->child_str1() == "text in child";
}
TEST(CppGeneratedCode, PassProxyToCProxy) {
TestModel model;
model.mutable_child_model_1()->set_child_str1("text in child");
EXPECT_TRUE(ProxyToCProxyMethod(model.mutable_child_model_1()));
}

Loading…
Cancel
Save