[Upb C++]Add ::protos::ClearMessage and DeepCopy apis.

PiperOrigin-RevId: 542903995
pull/13171/head
Protobuf Team Bot 1 year ago committed by Copybara-Service
parent 923e8b756f
commit 496e2fd555
  1. 33
      protos/protos.h
  2. 4
      protos_generator/gen_messages.cc
  3. 73
      protos_generator/tests/test_generated.cc

@ -124,6 +124,39 @@ typename T::Proxy CloneMessage(Ptr<T> message, upb::Arena& arena) {
arena.ptr());
}
template <typename T>
void DeepCopy(Ptr<const T> source_message, Ptr<T> target_message) {
upb_Message_DeepCopy(
target_message->msg(), source_message->msg(), T::minitable(),
static_cast<upb_Arena*>(target_message->GetInternalArena()));
}
template <typename T>
void DeepCopy(Ptr<const T> source_message, T* target_message) {
DeepCopy(source_message, protos::Ptr(target_message));
}
template <typename T>
void DeepCopy(const T* source_message, Ptr<T> target_message) {
DeepCopy(protos::Ptr(source_message), target_message);
}
template <typename T>
void DeepCopy(const T* source_message, T* target_message) {
DeepCopy(protos::Ptr(source_message), protos::Ptr(target_message));
}
template <typename T>
void ClearMessage(Ptr<T> message) {
static_assert(!std::is_const_v<T>, "");
upb_Message_Clear(message->msg(), T::minitable());
}
template <typename T>
void ClearMessage(T* message) {
ClearMessage(protos::Ptr(message));
}
// begin:github_only
// This type exists to work around an absl type that has not yet been
// released.

@ -245,6 +245,10 @@ void WriteModelProxyDeclaration(const protobuf::Descriptor* descriptor,
msg_ = m.msg_;
arena_ = m.arena_;
}
$0Proxy($0* m) : internal::$0Access() {
msg_ = m->msg_;
arena_ = m->arena_;
}
$0Proxy operator=(const $0Proxy& m) {
msg_ = m.msg_;
arena_ = m.arena_;

@ -882,3 +882,76 @@ TEST(CppGeneratedCode, PassProxyToCProxy) {
model.mutable_child_model_1()->set_child_str1("text in child");
EXPECT_TRUE(ProxyToCProxyMethod(model.mutable_child_model_1()));
}
TEST(CppGeneratedCode, PtrImplicitConversion) {
TestModel model;
model.set_int64(5);
::protos::Ptr<TestModel> model_ptr = &model;
EXPECT_EQ(model_ptr->int64(), 5);
}
TEST(CppGeneratedCode, ClearSubMessage) {
// Fill model.
TestModel model;
model.set_int64(5);
auto new_child = model.mutable_child_model_1();
new_child->set_child_str1("text in child");
ThemeExtension extension1;
extension1.set_ext_name("name in extension");
EXPECT_TRUE(::protos::SetExtension(model, theme, extension1).ok());
EXPECT_TRUE(model.mutable_child_model_1()->has_child_str1());
// Clear using Ptr<T>
::protos::ClearMessage(model.mutable_child_model_1());
EXPECT_FALSE(model.mutable_child_model_1()->has_child_str1());
}
TEST(CppGeneratedCode, ClearMessage) {
// Fill model.
TestModel model;
model.set_int64(5);
model.set_str2("Hello");
auto new_child = model.add_child_models();
ASSERT_TRUE(new_child.ok());
new_child.value()->set_child_str1("text in child");
ThemeExtension extension1;
extension1.set_ext_name("name in extension");
EXPECT_TRUE(::protos::SetExtension(model, theme, extension1).ok());
// Clear using T*
::protos::ClearMessage(&model);
// Verify that scalars, repeated fields and extensions are cleared.
EXPECT_FALSE(model.has_int64());
EXPECT_FALSE(model.has_str2());
EXPECT_TRUE(model.child_models().empty());
EXPECT_FALSE(::protos::HasExtension(model, theme));
}
TEST(CppGeneratedCode, DeepCopy) {
// Fill model.
TestModel model;
model.set_int64(5);
model.set_str2("Hello");
auto new_child = model.add_child_models();
ASSERT_TRUE(new_child.ok());
new_child.value()->set_child_str1("text in child");
ThemeExtension extension1;
extension1.set_ext_name("name in extension");
EXPECT_TRUE(::protos::SetExtension(model, theme, extension1).ok());
TestModel target;
target.set_b1(true);
::protos::DeepCopy(&model, &target);
EXPECT_FALSE(target.b1()) << "Target was not cleared before copying content";
EXPECT_EQ(target.str2(), "Hello");
EXPECT_TRUE(::protos::HasExtension(target, theme));
}
// TODO(b/288491350) : Add BUILD rule to test failures below.
#ifdef TEST_CLEAR_MESSAGE_FAILURE
TEST(CppGeneratedCode, ClearConstMessageShouldFail) {
// Fill model.
TestModel model;
model.set_int64(5);
model.set_str2("Hello");
// Only mutable_ can be cleared not Ptr<const T>.
::protos::ClearMessage(model.child_model_1());
}
#endif

Loading…
Cancel
Save