[Upb C++] Fix: Map setter does not follow value semantics when value is a message.

PiperOrigin-RevId: 525165538
pull/13171/head
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent fa1c2a6d29
commit de31ae9817
  1. 13
      protos_generator/gen_accessors.cc
  2. 1
      protos_generator/protoc-gen-upb-protos.cc
  3. 7
      protos_generator/tests/test_generated.cc

@ -31,6 +31,7 @@
#include "google/protobuf/descriptor.h"
#include "protos_generator/gen_utils.h"
#include "protos_generator/output.h"
#include "upbc/common.h"
#include "upbc/keywords.h"
#include "upbc/names.h"
@ -486,23 +487,27 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
output(
R"cc(
bool $0::set_$1($2 key, $3 value) {
$6return $4_$8_set(msg_, $7, ($5*)value->msg(), arena_);
upb_Message* clone = upb_Message_DeepClone(value->msg(), &$9, arena_);
$6return $4_$8_set(msg_, $7, ($5*)clone, arena_);
}
)cc",
class_name, resolved_field_name, CppConstType(key),
MessagePtrConstType(val, /* is_const */ true), MessageName(message),
MessageName(val->message_type()), optional_conversion_code,
converted_key_name, upbc_name);
converted_key_name, upbc_name,
::upbc::MessageInit(val->message_type()->full_name()));
output(
R"cc(
bool $0::set_$1($2 key, $3 value) {
$6return $4_$8_set(msg_, $7, ($5*)value->msg(), arena_);
upb_Message* clone = upb_Message_DeepClone(value->msg(), &$9, arena_);
$6return $4_$8_set(msg_, $7, ($5*)clone, arena_);
}
)cc",
class_name, resolved_field_name, CppConstType(key),
MessagePtrConstType(val, /* is_const */ false), MessageName(message),
MessageName(val->message_type()), optional_conversion_code,
converted_key_name, upbc_name);
converted_key_name, upbc_name,
::upbc::MessageInit(val->message_type()->full_name()));
output(
R"cc(
absl::StatusOr<$3> $0::get_$1($2 key) {

@ -197,6 +197,7 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output,
R"cc(
#include <stddef.h>
#include "absl/strings/string_view.h"
#include "upb/message/copy.h"
#include "upb/message/internal.h"
#include "protos/protos.h"
#include "$0"

@ -404,16 +404,21 @@ TEST(CppGeneratedCode, RepeatedStrings) {
TEST(CppGeneratedCode, MessageMapInt32KeyMessageValue) {
const int key_test_value = 3;
::protos::Arena arena;
::protos::Arena child_arena;
auto test_model = ::protos::CreateMessage<TestModel>(arena);
EXPECT_EQ(0, test_model.child_map_size());
test_model.clear_child_map();
EXPECT_EQ(0, test_model.child_map_size());
auto child_model1 = ::protos::CreateMessage<ChildModel1>(arena);
auto child_model1 = ::protos::CreateMessage<ChildModel1>(child_arena);
child_model1.set_child_str1("abc");
test_model.set_child_map(key_test_value, child_model1);
auto map_result = test_model.get_child_map(key_test_value);
EXPECT_EQ(true, map_result.ok());
EXPECT_EQ("abc", map_result.value()->child_str1());
// Now mutate original child model to verify that value semantics are
// preserved.
child_model1.set_child_str1("abc V2");
EXPECT_EQ("abc", map_result.value()->child_str1());
test_model.delete_child_map(key_test_value);
auto map_result_after_delete = test_model.get_child_map(key_test_value);
EXPECT_EQ(false, map_result_after_delete.ok());

Loading…
Cancel
Save