1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7
8 /* Test of mini table accessors.
9 *
10 * Messages are created and mutated using generated code, and then
11 * accessed through reflective APIs exposed through mini table accessors.
12 */
13
14 #include "upb/message/accessors.h"
15
16 #include <string.h>
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <string>
21
22 #include <gtest/gtest.h>
23 #include "google/protobuf/test_messages_proto2.upb.h"
24 #include "google/protobuf/test_messages_proto2.upb_minitable.h"
25 #include "google/protobuf/test_messages_proto3.upb.h"
26 #include "google/protobuf/test_messages_proto3.upb_minitable.h"
27 #include "upb/base/descriptor_constants.h"
28 #include "upb/base/status.h"
29 #include "upb/base/string_view.h"
30 #include "upb/base/upcast.h"
31 #include "upb/mem/arena.h"
32 #include "upb/message/array.h"
33 #include "upb/message/message.h"
34 #include "upb/mini_descriptor/decode.h"
35 #include "upb/mini_descriptor/internal/encode.hpp"
36 #include "upb/mini_descriptor/internal/modifiers.h"
37 #include "upb/mini_table/field.h"
38 #include "upb/mini_table/message.h"
39
40 // Must be last
41 #include "upb/port/def.inc"
42
43 namespace {
44
45 // Proto2 test messages field numbers used for reflective access.
46 const uint32_t kFieldOptionalInt32 = 1;
47 const uint32_t kFieldOptionalUInt32 = 3;
48 const uint32_t kFieldOptionalBool = 13;
49 const uint32_t kFieldOptionalString = 14;
50 const uint32_t kFieldOptionalNestedMessage = 18;
51 const uint32_t kFieldOptionalRepeatedInt32 = 31;
52 const uint32_t kFieldOptionalRepeatedNestedMessage = 48;
53 const uint32_t kFieldOptionalNestedMessageA = 1;
54 const uint32_t kFieldOptionalOneOfUInt32 = 111;
55 const uint32_t kFieldOptionalOneOfString = 113;
56
57 const uint32_t kFieldProto3OptionalInt64 = 2;
58 const uint32_t kFieldProto3OptionalUInt64 = 4;
59
60 const char kTestStr1[] = "Hello1";
61 const char kTestStr2[] = "Hello2";
62 const int32_t kTestInt32 = 567;
63 const int32_t kTestUInt32 = 0xF1234567;
64 const uint64_t kTestUInt64 = 0xFEDCBAFF87654321;
65
find_proto3_field(int field_number)66 const upb_MiniTableField* find_proto3_field(int field_number) {
67 return upb_MiniTable_FindFieldByNumber(
68 &protobuf_0test_0messages__proto3__TestAllTypesProto3_msg_init,
69 field_number);
70 }
71
find_proto2_field(int field_number)72 const upb_MiniTableField* find_proto2_field(int field_number) {
73 return upb_MiniTable_FindFieldByNumber(
74 &protobuf_0test_0messages__proto2__TestAllTypesProto2_msg_init,
75 field_number);
76 }
77
TEST(GeneratedCode,HazzersProto2)78 TEST(GeneratedCode, HazzersProto2) {
79 upb_Arena* arena = upb_Arena_New();
80 protobuf_test_messages_proto2_TestAllTypesProto2* msg =
81 protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
82
83 // Scalar/Boolean.
84 const upb_MiniTableField* optional_bool_field =
85 find_proto2_field(kFieldOptionalBool);
86 EXPECT_EQ(false,
87 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_bool_field));
88 protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_bool(msg, true);
89 EXPECT_EQ(true,
90 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_bool_field));
91 upb_Message_ClearBaseField(UPB_UPCAST(msg), optional_bool_field);
92 EXPECT_EQ(false,
93 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_bool_field));
94 EXPECT_EQ(
95 false,
96 protobuf_test_messages_proto2_TestAllTypesProto2_optional_bool(msg));
97
98 // String.
99 const upb_MiniTableField* optional_string_field =
100 find_proto2_field(kFieldOptionalString);
101 EXPECT_EQ(false,
102 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_string_field));
103 protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_string(
104 msg, upb_StringView_FromString(kTestStr1));
105 EXPECT_EQ(true,
106 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_string_field));
107 EXPECT_EQ(
108 strlen(kTestStr1),
109 protobuf_test_messages_proto2_TestAllTypesProto2_optional_string(msg)
110 .size);
111 upb_Message_ClearBaseField(UPB_UPCAST(msg), optional_string_field);
112 EXPECT_EQ(false,
113 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_string_field));
114 EXPECT_EQ(
115 0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_string(msg)
116 .size);
117
118 // Message.
119 const upb_MiniTableField* optional_message_field =
120 find_proto2_field(kFieldOptionalNestedMessage);
121 EXPECT_EQ(false,
122 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_message_field));
123 protobuf_test_messages_proto2_TestAllTypesProto2_mutable_optional_nested_message(
124 msg, arena);
125 EXPECT_EQ(true,
126 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_message_field));
127 upb_Message_ClearBaseField(UPB_UPCAST(msg), optional_message_field);
128 EXPECT_EQ(false,
129 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_message_field));
130 EXPECT_EQ(
131 true,
132 protobuf_test_messages_proto2_TestAllTypesProto2_optional_nested_message(
133 msg) == nullptr);
134
135 // One of.
136 const upb_MiniTableField* optional_oneof_uint32_field =
137 find_proto2_field(kFieldOptionalOneOfUInt32);
138 const upb_MiniTableField* optional_oneof_string_field =
139 find_proto2_field(kFieldOptionalOneOfString);
140
141 EXPECT_EQ(false, upb_Message_HasBaseField(UPB_UPCAST(msg),
142 optional_oneof_uint32_field));
143 EXPECT_EQ(false, upb_Message_HasBaseField(UPB_UPCAST(msg),
144 optional_oneof_string_field));
145 protobuf_test_messages_proto2_TestAllTypesProto2_set_oneof_uint32(msg, 123);
146 EXPECT_EQ(true, upb_Message_HasBaseField(UPB_UPCAST(msg),
147 optional_oneof_uint32_field));
148 EXPECT_EQ(false, upb_Message_HasBaseField(UPB_UPCAST(msg),
149 optional_oneof_string_field));
150 protobuf_test_messages_proto2_TestAllTypesProto2_set_oneof_string(
151 msg, upb_StringView_FromString(kTestStr1));
152 EXPECT_EQ(false, upb_Message_HasBaseField(UPB_UPCAST(msg),
153 optional_oneof_uint32_field));
154 EXPECT_EQ(true, upb_Message_HasBaseField(UPB_UPCAST(msg),
155 optional_oneof_string_field));
156 upb_Message_ClearBaseField(UPB_UPCAST(msg), optional_oneof_uint32_field);
157 EXPECT_EQ(false, upb_Message_HasBaseField(UPB_UPCAST(msg),
158 optional_oneof_uint32_field));
159 EXPECT_EQ(true, upb_Message_HasBaseField(UPB_UPCAST(msg),
160 optional_oneof_string_field));
161 upb_Message_ClearBaseField(UPB_UPCAST(msg), optional_oneof_string_field);
162 EXPECT_EQ(false, upb_Message_HasBaseField(UPB_UPCAST(msg),
163 optional_oneof_uint32_field));
164 EXPECT_EQ(false, upb_Message_HasBaseField(UPB_UPCAST(msg),
165 optional_oneof_string_field));
166
167 upb_Arena_Free(arena);
168 }
169
TEST(GeneratedCode,ScalarsProto2)170 TEST(GeneratedCode, ScalarsProto2) {
171 upb_Arena* arena = upb_Arena_New();
172 protobuf_test_messages_proto2_TestAllTypesProto2* msg =
173 protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
174
175 const upb_MiniTableField* optional_int32_field =
176 find_proto2_field(kFieldOptionalInt32);
177
178 EXPECT_EQ(
179 0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_int32(msg));
180
181 EXPECT_EQ(0, upb_Message_GetInt32(UPB_UPCAST(msg), optional_int32_field, 0));
182 upb_Message_SetBaseFieldInt32(UPB_UPCAST(msg), optional_int32_field,
183 kTestInt32);
184 EXPECT_EQ(true,
185 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_int32_field));
186 EXPECT_EQ(kTestInt32,
187 upb_Message_GetInt32(UPB_UPCAST(msg), optional_int32_field, 0));
188 EXPECT_EQ(
189 kTestInt32,
190 protobuf_test_messages_proto2_TestAllTypesProto2_optional_int32(msg));
191
192 const upb_MiniTableField* optional_uint32_field =
193 find_proto2_field(kFieldOptionalUInt32);
194
195 EXPECT_EQ(
196 0, protobuf_test_messages_proto2_TestAllTypesProto2_optional_uint32(msg));
197 EXPECT_EQ(0,
198 upb_Message_GetUInt32(UPB_UPCAST(msg), optional_uint32_field, 0));
199 upb_Message_SetBaseFieldUInt32(UPB_UPCAST(msg), optional_uint32_field,
200 kTestUInt32);
201 EXPECT_EQ(kTestUInt32,
202 upb_Message_GetUInt32(UPB_UPCAST(msg), optional_uint32_field, 0));
203 EXPECT_EQ(
204 kTestUInt32,
205 protobuf_test_messages_proto2_TestAllTypesProto2_optional_uint32(msg));
206
207 upb_Arena_Free(arena);
208 }
209
TEST(GeneratedCode,ScalarProto3)210 TEST(GeneratedCode, ScalarProto3) {
211 upb_Arena* arena = upb_Arena_New();
212 protobuf_test_messages_proto3_TestAllTypesProto3* msg =
213 protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
214
215 const upb_MiniTableField* optional_int64_field =
216 find_proto3_field(kFieldProto3OptionalInt64);
217 const upb_MiniTableField* optional_uint64_field =
218 find_proto3_field(kFieldProto3OptionalUInt64);
219
220 EXPECT_EQ(
221 0, protobuf_test_messages_proto3_TestAllTypesProto3_optional_int64(msg));
222 upb_Message_SetBaseFieldInt64(UPB_UPCAST(msg), optional_int64_field, -1);
223 EXPECT_EQ(
224 -1, protobuf_test_messages_proto3_TestAllTypesProto3_optional_int64(msg));
225 EXPECT_EQ(-1, upb_Message_GetInt64(UPB_UPCAST(msg), optional_int64_field, 0));
226
227 EXPECT_EQ(
228 0, protobuf_test_messages_proto3_TestAllTypesProto3_optional_uint64(msg));
229 upb_Message_SetBaseFieldUInt64(UPB_UPCAST(msg), optional_uint64_field,
230 kTestUInt64);
231 EXPECT_EQ(
232 kTestUInt64,
233 protobuf_test_messages_proto3_TestAllTypesProto3_optional_uint64(msg));
234 EXPECT_EQ(kTestUInt64,
235 upb_Message_GetUInt64(UPB_UPCAST(msg), optional_uint64_field, 0));
236
237 upb_Arena_Free(arena);
238 }
239
TEST(GeneratedCode,Strings)240 TEST(GeneratedCode, Strings) {
241 upb_Arena* arena = upb_Arena_New();
242 protobuf_test_messages_proto2_TestAllTypesProto2* msg =
243 protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
244
245 const upb_MiniTableField* optional_string_field =
246 find_proto2_field(kFieldOptionalString);
247
248 // Test default.
249 EXPECT_EQ(false,
250 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_string_field));
251 // Test read after write using C.
252 protobuf_test_messages_proto2_TestAllTypesProto2_set_optional_string(
253 msg, upb_StringView_FromString(kTestStr1));
254 EXPECT_EQ(true,
255 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_string_field));
256 upb_StringView value = upb_Message_GetString(
257 UPB_UPCAST(msg), optional_string_field, upb_StringView{nullptr, 0});
258 std::string read_value = std::string(value.data, value.size);
259 EXPECT_EQ(kTestStr1, read_value);
260 // Clear.
261 upb_Message_ClearBaseField(UPB_UPCAST(msg), optional_string_field);
262 EXPECT_EQ(false,
263 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_string_field));
264 EXPECT_EQ(
265 false,
266 protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_string(
267 msg));
268 upb_Message_SetBaseFieldString(UPB_UPCAST(msg), optional_string_field,
269 upb_StringView_FromString(kTestStr2));
270 EXPECT_EQ(true,
271 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_string_field));
272 EXPECT_EQ(
273 true,
274 protobuf_test_messages_proto2_TestAllTypesProto2_has_optional_string(
275 msg));
276 value = protobuf_test_messages_proto2_TestAllTypesProto2_optional_string(msg);
277 read_value = std::string(value.data, value.size);
278 EXPECT_EQ(kTestStr2, read_value);
279
280 upb_Arena_Free(arena);
281 }
282
TEST(GeneratedCode,SubMessage)283 TEST(GeneratedCode, SubMessage) {
284 upb_Arena* arena = upb_Arena_New();
285 protobuf_test_messages_proto2_TestAllTypesProto2* msg =
286 protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
287
288 const upb_MiniTableField* optional_message_field =
289 find_proto2_field(kFieldOptionalNestedMessage);
290
291 const upb_Message* test_message =
292 upb_Message_GetMessage(UPB_UPCAST(msg), optional_message_field);
293 EXPECT_EQ(nullptr, test_message);
294
295 EXPECT_EQ(false,
296 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_message_field));
297
298 // Get mutable using C API.
299 protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage* nested_message =
300 protobuf_test_messages_proto2_TestAllTypesProto2_mutable_optional_nested_message(
301 msg, arena);
302 EXPECT_EQ(true, nested_message != nullptr);
303 EXPECT_EQ(true,
304 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_message_field));
305 protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage_set_a(
306 nested_message, 5);
307
308 // Read back using mini table API.
309 const upb_Message* sub_message =
310 upb_Message_GetMessage(UPB_UPCAST(msg), optional_message_field);
311 EXPECT_EQ(true, sub_message != nullptr);
312
313 const upb_MiniTableField* nested_message_a_field =
314 upb_MiniTable_FindFieldByNumber(
315 &protobuf_0test_0messages__proto2__TestAllTypesProto2__NestedMessage_msg_init,
316 kFieldOptionalNestedMessageA);
317 EXPECT_EQ(5, upb_Message_GetInt32(sub_message, nested_message_a_field, 0));
318
319 upb_Message_ClearBaseField(UPB_UPCAST(msg), optional_message_field);
320 EXPECT_EQ(
321 nullptr,
322 protobuf_test_messages_proto2_TestAllTypesProto2_optional_nested_message(
323 msg));
324 EXPECT_EQ(false,
325 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_message_field));
326
327 upb_Message* new_nested_message = UPB_UPCAST(
328 protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage_new(
329 arena));
330 upb_Message_SetBaseFieldInt32(new_nested_message, nested_message_a_field,
331 123);
332 upb_Message_SetMessage(UPB_UPCAST(msg), optional_message_field,
333 new_nested_message);
334
335 upb_Message* mutable_message = upb_Message_GetOrCreateMutableMessage(
336 UPB_UPCAST(msg),
337 &protobuf_0test_0messages__proto2__TestAllTypesProto2_msg_init,
338 optional_message_field, arena);
339 EXPECT_EQ(
340 true,
341 protobuf_test_messages_proto2_TestAllTypesProto2_optional_nested_message(
342 msg) != nullptr);
343 EXPECT_EQ(true,
344 upb_Message_HasBaseField(UPB_UPCAST(msg), optional_message_field));
345 EXPECT_EQ(123,
346 upb_Message_GetInt32(mutable_message, nested_message_a_field, 0));
347
348 upb_Arena_Free(arena);
349 }
350
TEST(GeneratedCode,RepeatedScalar)351 TEST(GeneratedCode, RepeatedScalar) {
352 upb_Arena* arena = upb_Arena_New();
353 protobuf_test_messages_proto2_TestAllTypesProto2* msg =
354 protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
355
356 const upb_MiniTableField* repeated_int32_field =
357 find_proto2_field(kFieldOptionalRepeatedInt32);
358
359 size_t len;
360 const int32_t* arr =
361 protobuf_test_messages_proto2_TestAllTypesProto2_repeated_int32(msg,
362 &len);
363 // Test Get/Set Array values, validate with C API.
364 EXPECT_EQ(0, len);
365 EXPECT_EQ(nullptr, arr);
366 EXPECT_EQ(nullptr,
367 upb_Message_GetArray(UPB_UPCAST(msg), repeated_int32_field));
368 protobuf_test_messages_proto2_TestAllTypesProto2_resize_repeated_int32(
369 msg, 10, arena);
370 int32_t* mutable_values =
371 protobuf_test_messages_proto2_TestAllTypesProto2_mutable_repeated_int32(
372 msg, &len);
373 mutable_values[5] = 123;
374 const upb_Array* readonly_arr =
375 upb_Message_GetArray(UPB_UPCAST(msg), repeated_int32_field);
376 EXPECT_EQ(123, upb_Array_Get(readonly_arr, 5).int32_val);
377
378 upb_MessageValue new_value;
379 new_value.int32_val = 567;
380 upb_Array* mutable_array =
381 upb_Message_GetMutableArray(UPB_UPCAST(msg), repeated_int32_field);
382 upb_Array_Set(mutable_array, 5, new_value);
383 EXPECT_EQ(new_value.int32_val,
384 protobuf_test_messages_proto2_TestAllTypesProto2_repeated_int32(
385 msg, &len)[5]);
386
387 // Test resize.
388 bool result = upb_Array_Resize(mutable_array, 20, arena);
389 EXPECT_EQ(true, result);
390 upb_Array_Set(mutable_array, 19, new_value);
391 EXPECT_EQ(new_value.int32_val,
392 protobuf_test_messages_proto2_TestAllTypesProto2_repeated_int32(
393 msg, &len)[19]);
394 upb_Array_Resize(mutable_array, 0, arena);
395 const int32_t* zero_length_array =
396 protobuf_test_messages_proto2_TestAllTypesProto2_repeated_int32(msg,
397 &len);
398 EXPECT_EQ(0, len);
399 EXPECT_EQ(true, zero_length_array != nullptr);
400
401 upb_Arena_Free(arena);
402 }
403
TEST(GeneratedCode,RepeatedMessage)404 TEST(GeneratedCode, RepeatedMessage) {
405 upb_Arena* arena = upb_Arena_New();
406 protobuf_test_messages_proto2_TestAllTypesProto2* msg =
407 protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
408
409 const upb_MiniTableField* repeated_nested_message_field =
410 find_proto2_field(kFieldOptionalRepeatedNestedMessage);
411 upb_Message* nested_message = (upb_Message*)
412 protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage_new(arena);
413
414 upb_Array* array = upb_Message_GetOrCreateMutableArray(
415 UPB_UPCAST(msg), repeated_nested_message_field, arena);
416 upb_MessageValue new_value;
417 new_value.msg_val = nested_message;
418 EXPECT_TRUE(upb_Array_Append(array, new_value, arena));
419
420 EXPECT_EQ(nested_message, upb_Array_GetMutable(array, 0).msg);
421 EXPECT_EQ(nested_message, upb_Array_Get(array, 0).msg_val);
422
423 upb_Arena_Free(arena);
424 }
425
TEST(GeneratedCode,GetMutableMessage)426 TEST(GeneratedCode, GetMutableMessage) {
427 upb_Arena* arena = upb_Arena_New();
428 protobuf_test_messages_proto2_TestAllTypesProto2* msg =
429 protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
430 // Message.
431 const upb_MiniTableField* optional_message_field =
432 find_proto2_field(kFieldOptionalNestedMessage);
433 upb_Message* msg1 = upb_Message_GetOrCreateMutableMessage(
434 UPB_UPCAST(msg),
435 &protobuf_0test_0messages__proto2__TestAllTypesProto2_msg_init,
436 optional_message_field, arena);
437 upb_Message* msg2 = upb_Message_GetOrCreateMutableMessage(
438 UPB_UPCAST(msg),
439 &protobuf_0test_0messages__proto2__TestAllTypesProto2_msg_init,
440 optional_message_field, arena);
441 // Verify that newly constructed sub message is stored in msg.
442 EXPECT_EQ(msg1, msg2);
443
444 upb_Arena_Free(arena);
445 }
446
TEST(GeneratedCode,EnumClosedCheck)447 TEST(GeneratedCode, EnumClosedCheck) {
448 upb_Arena* arena = upb_Arena_New();
449
450 upb::MtDataEncoder e;
451 e.StartMessage(0);
452 e.PutField(kUpb_FieldType_Int32, 4, 0);
453 e.PutField(kUpb_FieldType_Enum, 5, 0);
454
455 upb_Status status;
456 upb_Status_Clear(&status);
457 upb_MiniTable* table =
458 upb_MiniTable_Build(e.data().data(), e.data().size(), arena, &status);
459
460 const upb_MiniTableField* enumField = &table->UPB_PRIVATE(fields)[1];
461 EXPECT_EQ(upb_MiniTableField_Type(enumField), kUpb_FieldType_Enum);
462 EXPECT_FALSE(upb_MiniTableField_IsClosedEnum(enumField));
463
464 upb::MtDataEncoder e2;
465 e2.StartMessage(0);
466 e2.PutField(kUpb_FieldType_Int32, 4, 0);
467 e2.PutField(kUpb_FieldType_Enum, 6, kUpb_FieldModifier_IsClosedEnum);
468
469 upb_Status_Clear(&status);
470 table =
471 upb_MiniTable_Build(e2.data().data(), e2.data().size(), arena, &status);
472
473 const upb_MiniTableField* closedEnumField = &table->UPB_PRIVATE(fields)[1];
474 EXPECT_EQ(upb_MiniTableField_Type(closedEnumField), kUpb_FieldType_Enum);
475 EXPECT_TRUE(upb_MiniTableField_IsClosedEnum(closedEnumField));
476 upb_Arena_Free(arena);
477 }
478
TEST(GeneratedCode,OneofClear)479 TEST(GeneratedCode, OneofClear) {
480 upb_Arena* arena = upb_Arena_New();
481
482 protobuf_test_messages_proto2_TestAllTypesProto2* msg =
483 protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
484
485 const upb_MiniTable* table =
486 &protobuf_0test_0messages__proto2__TestAllTypesProto2_msg_init;
487
488 // oneof_uint32
489 const upb_MiniTableField* oneofField =
490 upb_MiniTable_FindFieldByNumber(table, 111);
491 EXPECT_TRUE(upb_MiniTableField_IsInOneof(oneofField));
492 protobuf_test_messages_proto2_TestAllTypesProto2_set_oneof_uint32(msg, 522);
493 EXPECT_TRUE(
494 protobuf_test_messages_proto2_TestAllTypesProto2_has_oneof_uint32(msg));
495
496 upb_Message_ClearOneof((upb_Message*)msg, table, oneofField);
497 EXPECT_FALSE(
498 protobuf_test_messages_proto2_TestAllTypesProto2_has_oneof_uint32(msg));
499
500 upb_Arena_Free(arena);
501 }
502
TEST(GeneratedCode,OneofAccess)503 TEST(GeneratedCode, OneofAccess) {
504 upb_Arena* arena = upb_Arena_New();
505
506 protobuf_test_messages_proto2_TestAllTypesProto2* msg =
507 protobuf_test_messages_proto2_TestAllTypesProto2_new(arena);
508
509 const upb_MiniTable* table =
510 &protobuf_0test_0messages__proto2__TestAllTypesProto2_msg_init;
511
512 // oneof_uint32
513 const upb_MiniTableField* oneofField =
514 upb_MiniTable_FindFieldByNumber(table, 111);
515 EXPECT_TRUE(upb_MiniTableField_IsInOneof(oneofField));
516
517 const upb_MiniTableField* oneOfFirstFetch =
518 upb_Message_WhichOneof((upb_Message*)msg, table, oneofField);
519 // one of not set, so should initially yield nullptr
520 EXPECT_EQ(oneOfFirstFetch, nullptr);
521
522 protobuf_test_messages_proto2_TestAllTypesProto2_set_oneof_uint32(msg, 522);
523 const upb_MiniTableField* oneOfSecondFetch =
524 upb_Message_WhichOneof((upb_Message*)msg, table, oneofField);
525 // this oneof has now been set, so should yield the MiniTableField
526 EXPECT_EQ(oneOfSecondFetch, oneofField);
527
528 upb_Arena_Free(arena);
529 }
530
531 } // namespace
532