#include "upb/message/merge.h" #include #include #include #include "google/protobuf/test_messages_proto2.upb.h" #include "google/protobuf/test_messages_proto2.upb_minitable.h" #include "upb/base/string_view.h" #include "upb/base/upcast.h" #include "upb/mem/arena.h" #include "upb/message/accessors.h" #include "upb/mini_table/field.h" #include "upb/mini_table/message.h" // Must be last. #include "upb/port/def.inc" namespace { // Proto2 test messages field numbers used for reflective access. const uint32_t kFieldOptionalInt32 = 1; const uint32_t kFieldOptionalString = 14; const char kTestStr1[] = "Hello1"; const int32_t kTestInt32 = 567; const upb_MiniTableField* find_proto2_field(int field_number) { return upb_MiniTable_FindFieldByNumber( &protobuf_0test_0messages__proto2__TestAllTypesProto2_msg_init, field_number); } TEST(GeneratedCode, MergeMessageScalarAndString) { upb_Arena* source_arena = upb_Arena_New(); protobuf_test_messages_proto2_TestAllTypesProto2* msg = protobuf_test_messages_proto2_TestAllTypesProto2_new(source_arena); const upb_MiniTableField* optional_int32_field = find_proto2_field(kFieldOptionalInt32); const upb_MiniTableField* optional_string_field = find_proto2_field(kFieldOptionalString); upb_Message_SetInt32(UPB_UPCAST(msg), optional_int32_field, kTestInt32, nullptr); char* string_in_arena = (char*)upb_Arena_Malloc(source_arena, sizeof(kTestStr1)); memcpy(string_in_arena, kTestStr1, sizeof(kTestStr1)); upb_Message_SetString( UPB_UPCAST(msg), optional_string_field, upb_StringView_FromDataAndSize(string_in_arena, sizeof(kTestStr1) - 1), source_arena); upb_Arena* arena = upb_Arena_New(); protobuf_test_messages_proto2_TestAllTypesProto2* clone = protobuf_test_messages_proto2_TestAllTypesProto2_new(arena); EXPECT_TRUE( (protobuf_test_messages_proto2_TestAllTypesProto2*)upb_Message_MergeFrom( UPB_UPCAST(clone), UPB_UPCAST(msg), &protobuf_0test_0messages__proto2__TestAllTypesProto2_msg_init, nullptr, arena)); // After cloning overwrite values and destroy source arena for MSAN. memset(string_in_arena, 0, sizeof(kTestStr1)); upb_Arena_Free(source_arena); EXPECT_TRUE( upb_Message_HasBaseField(UPB_UPCAST(clone), optional_int32_field)); EXPECT_EQ(upb_Message_GetInt32(UPB_UPCAST(clone), optional_int32_field, 0), kTestInt32); EXPECT_TRUE( upb_Message_HasBaseField(UPB_UPCAST(clone), optional_string_field)); EXPECT_EQ(upb_Message_GetString(UPB_UPCAST(clone), optional_string_field, upb_StringView_FromDataAndSize(nullptr, 0)) .size, sizeof(kTestStr1) - 1); EXPECT_TRUE(upb_StringView_IsEqual( upb_Message_GetString(UPB_UPCAST(clone), optional_string_field, upb_StringView_FromDataAndSize(nullptr, 0)), upb_StringView_FromString(kTestStr1))); upb_Arena_Free(arena); } } // namespace