| #include "upb/message/merge.h" | |
| #include <cstdint> | |
| #include <cstring> | |
| #include <gtest/gtest.h> | |
| #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 |