1 #include "upb/message/merge.h"
2
3 #include <cstdint>
4 #include <cstring>
5
6 #include <gtest/gtest.h>
7 #include "google/protobuf/test_messages_proto2.upb.h"
8 #include "google/protobuf/test_messages_proto2.upb_minitable.h"
9 #include "upb/base/string_view.h"
10 #include "upb/base/upcast.h"
11 #include "upb/mem/arena.h"
12 #include "upb/message/accessors.h"
13 #include "upb/mini_table/field.h"
14 #include "upb/mini_table/message.h"
15
16 // Must be last.
17 #include "upb/port/def.inc"
18
19 namespace {
20
21 // Proto2 test messages field numbers used for reflective access.
22 const uint32_t kFieldOptionalInt32 = 1;
23 const uint32_t kFieldOptionalString = 14;
24
25 const char kTestStr1[] = "Hello1";
26 const int32_t kTestInt32 = 567;
27
find_proto2_field(int field_number)28 const upb_MiniTableField* find_proto2_field(int field_number) {
29 return upb_MiniTable_FindFieldByNumber(
30 &protobuf_0test_0messages__proto2__TestAllTypesProto2_msg_init,
31 field_number);
32 }
33
TEST(GeneratedCode,MergeMessageScalarAndString)34 TEST(GeneratedCode, MergeMessageScalarAndString) {
35 upb_Arena* source_arena = upb_Arena_New();
36 protobuf_test_messages_proto2_TestAllTypesProto2* msg =
37 protobuf_test_messages_proto2_TestAllTypesProto2_new(source_arena);
38 const upb_MiniTableField* optional_int32_field =
39 find_proto2_field(kFieldOptionalInt32);
40 const upb_MiniTableField* optional_string_field =
41 find_proto2_field(kFieldOptionalString);
42 upb_Message_SetInt32(UPB_UPCAST(msg), optional_int32_field, kTestInt32,
43 nullptr);
44 char* string_in_arena =
45 (char*)upb_Arena_Malloc(source_arena, sizeof(kTestStr1));
46 memcpy(string_in_arena, kTestStr1, sizeof(kTestStr1));
47 upb_Message_SetString(
48 UPB_UPCAST(msg), optional_string_field,
49 upb_StringView_FromDataAndSize(string_in_arena, sizeof(kTestStr1) - 1),
50 source_arena);
51 upb_Arena* arena = upb_Arena_New();
52 protobuf_test_messages_proto2_TestAllTypesProto2* clone =
53 protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
54 EXPECT_TRUE(
55 (protobuf_test_messages_proto2_TestAllTypesProto2*)upb_Message_MergeFrom(
56 UPB_UPCAST(clone), UPB_UPCAST(msg),
57 &protobuf_0test_0messages__proto2__TestAllTypesProto2_msg_init,
58 nullptr, arena));
59 // After cloning overwrite values and destroy source arena for MSAN.
60 memset(string_in_arena, 0, sizeof(kTestStr1));
61 upb_Arena_Free(source_arena);
62 EXPECT_TRUE(
63 upb_Message_HasBaseField(UPB_UPCAST(clone), optional_int32_field));
64 EXPECT_EQ(upb_Message_GetInt32(UPB_UPCAST(clone), optional_int32_field, 0),
65 kTestInt32);
66 EXPECT_TRUE(
67 upb_Message_HasBaseField(UPB_UPCAST(clone), optional_string_field));
68 EXPECT_EQ(upb_Message_GetString(UPB_UPCAST(clone), optional_string_field,
69 upb_StringView_FromDataAndSize(nullptr, 0))
70 .size,
71 sizeof(kTestStr1) - 1);
72 EXPECT_TRUE(upb_StringView_IsEqual(
73 upb_Message_GetString(UPB_UPCAST(clone), optional_string_field,
74 upb_StringView_FromDataAndSize(nullptr, 0)),
75 upb_StringView_FromString(kTestStr1)));
76 upb_Arena_Free(arena);
77 }
78
79 } // namespace
80