Skip to content

Commit 3a3d697

Browse files
Change upb C generated map iteration function to not hand out MapEntry pointers.
Users relying on internal upb functions may be broken as these are meant to be *internal*. In the interim, users may need to update their code by using the new Map iteration API. PiperOrigin-RevId: 730929091
1 parent 19dcc4e commit 3a3d697

File tree

3 files changed

+87
-116
lines changed

3 files changed

+87
-116
lines changed

upb/message/copy_test.cc

Lines changed: 41 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -191,55 +191,49 @@ TEST(GeneratedCode, DeepCloneMessageMapField) {
191191
protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage_set_a(nested,
192192
0);
193193
upb_Arena_Free(source_arena);
194-
size_t iter = kUpb_Map_Begin;
195-
// Test map<int32, int32>.
196-
const protobuf_test_messages_proto2_TestAllTypesProto2_MapInt32DoubleEntry*
197-
int32_double_entry =
198-
protobuf_test_messages_proto2_TestAllTypesProto2_map_int32_double_next(
199-
clone, &iter);
200-
ASSERT_NE(int32_double_entry, nullptr);
201-
EXPECT_EQ(
202-
protobuf_test_messages_proto2_TestAllTypesProto2_MapInt32DoubleEntry_key(
203-
int32_double_entry),
204-
12);
205-
EXPECT_EQ(
206-
protobuf_test_messages_proto2_TestAllTypesProto2_MapInt32DoubleEntry_value(
207-
int32_double_entry),
208-
1200.5);
194+
// Test map<int32, double>.
195+
{
196+
int32_t key;
197+
double value;
198+
size_t iter = kUpb_Map_Begin;
199+
200+
ASSERT_TRUE(
201+
protobuf_test_messages_proto2_TestAllTypesProto2_map_int32_double_next(
202+
clone, &key, &value, &iter));
203+
EXPECT_EQ(key, 12);
204+
EXPECT_EQ(value, 1200.5);
205+
}
206+
209207
// Test map<string, string>.
210-
iter = kUpb_Map_Begin;
211-
const protobuf_test_messages_proto2_TestAllTypesProto2_MapStringStringEntry*
212-
string_string_entry =
213-
protobuf_test_messages_proto2_TestAllTypesProto2_map_string_string_next(
214-
clone, &iter);
215-
ASSERT_NE(string_string_entry, nullptr);
216-
EXPECT_TRUE(upb_StringView_IsEqual(
217-
protobuf_test_messages_proto2_TestAllTypesProto2_MapStringStringEntry_key(
218-
string_string_entry),
219-
upb_StringView_FromString("key1")));
220-
EXPECT_TRUE(upb_StringView_IsEqual(
221-
protobuf_test_messages_proto2_TestAllTypesProto2_MapStringStringEntry_value(
222-
string_string_entry),
223-
upb_StringView_FromString("value1")));
208+
{
209+
upb_StringView key;
210+
upb_StringView value;
211+
size_t iter = kUpb_Map_Begin;
212+
213+
ASSERT_TRUE(
214+
protobuf_test_messages_proto2_TestAllTypesProto2_map_string_string_next(
215+
clone, &key, &value, &iter));
216+
EXPECT_TRUE(upb_StringView_IsEqual(key, upb_StringView_FromString("key1")));
217+
EXPECT_TRUE(
218+
upb_StringView_IsEqual(value, upb_StringView_FromString("value1")));
219+
}
220+
224221
// Test map<string, NestedMessage>.
225-
iter = kUpb_Map_Begin;
226-
const protobuf_test_messages_proto2_TestAllTypesProto2_MapStringNestedMessageEntry*
227-
nested_message_entry =
228-
protobuf_test_messages_proto2_TestAllTypesProto2_map_string_nested_message_next(
229-
clone, &iter);
230-
ASSERT_NE(nested_message_entry, nullptr);
231-
EXPECT_TRUE(upb_StringView_IsEqual(
232-
protobuf_test_messages_proto2_TestAllTypesProto2_MapStringNestedMessageEntry_key(
233-
nested_message_entry),
234-
upb_StringView_FromString("nestedkey1")));
235-
const protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage*
236-
cloned_nested =
237-
protobuf_test_messages_proto2_TestAllTypesProto2_MapStringNestedMessageEntry_value(
238-
nested_message_entry);
239-
ASSERT_NE(cloned_nested, nullptr);
240-
EXPECT_EQ(protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage_a(
241-
cloned_nested),
242-
kTestNestedInt32);
222+
{
223+
upb_StringView key;
224+
const protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage* value;
225+
size_t iter = kUpb_Map_Begin;
226+
ASSERT_TRUE(
227+
protobuf_test_messages_proto2_TestAllTypesProto2_map_string_nested_message_next(
228+
clone, &key, &value, &iter));
229+
EXPECT_TRUE(
230+
upb_StringView_IsEqual(key, upb_StringView_FromString("nestedkey1")));
231+
ASSERT_NE(value, nullptr);
232+
EXPECT_EQ(
233+
protobuf_test_messages_proto2_TestAllTypesProto2_NestedMessage_a(value),
234+
kTestNestedInt32);
235+
}
236+
243237
upb_Arena_Free(arena);
244238
}
245239

upb/test/test_generated_code.cc

Lines changed: 31 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -505,15 +505,16 @@ static void check_string_map_empty(
505505
0,
506506
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_size(
507507
msg));
508+
509+
upb_StringView key;
510+
upb_StringView val;
508511
EXPECT_FALSE(
509512
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
510-
msg, &iter));
513+
msg, &key, &val, &iter));
511514
}
512515

513516
static void check_string_map_one_entry(
514517
protobuf_test_messages_proto3_TestAllTypesProto3* msg) {
515-
const protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry*
516-
const_ent;
517518
size_t iter;
518519
upb_StringView str;
519520

@@ -532,23 +533,15 @@ static void check_string_map_one_entry(
532533

533534
/* Test that iteration reveals a single k/v pair in the map. */
534535
iter = kUpb_Map_Begin;
535-
const_ent =
536-
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
537-
msg, &iter);
538-
ASSERT_NE(nullptr, const_ent);
539-
EXPECT_TRUE(upb_StringView_IsEqual(
540-
test_str_view,
541-
protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_key(
542-
const_ent)));
543-
EXPECT_TRUE(upb_StringView_IsEqual(
544-
test_str_view2,
545-
protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_value(
546-
const_ent)));
547-
548-
const_ent =
536+
upb_StringView key;
537+
upb_StringView val;
538+
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
539+
msg, &key, &val, &iter);
540+
EXPECT_TRUE(upb_StringView_IsEqual(test_str_view, key));
541+
EXPECT_TRUE(upb_StringView_IsEqual(test_str_view2, val));
542+
EXPECT_FALSE(
549543
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
550-
msg, &iter);
551-
EXPECT_EQ(nullptr, const_ent);
544+
msg, &key, &val, &iter));
552545
}
553546

554547
TEST(GeneratedCode, StringDoubleMap) {
@@ -580,8 +573,6 @@ TEST(GeneratedCode, StringMap) {
580573
upb_Arena* arena = upb_Arena_New();
581574
protobuf_test_messages_proto3_TestAllTypesProto3* msg =
582575
protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
583-
const protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry*
584-
const_ent;
585576
size_t iter, count;
586577

587578
check_string_map_empty(msg);
@@ -615,18 +606,11 @@ TEST(GeneratedCode, StringMap) {
615606
/* Test iteration */
616607
iter = kUpb_Map_Begin;
617608
count = 0;
618-
609+
upb_StringView key;
610+
upb_StringView val;
619611
while (
620-
(const_ent =
621-
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
622-
msg, &iter)) != nullptr) {
623-
upb_StringView key =
624-
protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_key(
625-
const_ent);
626-
upb_StringView val =
627-
protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_value(
628-
const_ent);
629-
612+
protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
613+
msg, &key, &val, &iter)) {
630614
count++;
631615
if (upb_StringView_IsEqual(key, test_str_view)) {
632616
EXPECT_TRUE(upb_StringView_IsEqual(val, test_str_view2));
@@ -652,16 +636,18 @@ static void check_int32_map_empty(
652636
EXPECT_EQ(
653637
0, protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_size(
654638
msg));
639+
640+
int32_t key;
641+
int32_t val;
655642
EXPECT_FALSE(
656643
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
657-
msg, &iter));
644+
msg, &key, &val, &iter));
658645
}
659646

660647
static void check_int32_map_one_entry(
661648
protobuf_test_messages_proto3_TestAllTypesProto3* msg) {
662-
const protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry*
663-
const_ent;
664649
size_t iter;
650+
int32_t key;
665651
int32_t val;
666652

667653
EXPECT_EQ(
@@ -678,31 +664,20 @@ static void check_int32_map_one_entry(
678664

679665
/* Test that iteration reveals a single k/v pair in the map. */
680666
iter = kUpb_Map_Begin;
681-
const_ent =
667+
EXPECT_TRUE(
682668
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
683-
msg, &iter);
684-
ASSERT_NE(nullptr, const_ent);
685-
EXPECT_EQ(
686-
test_int32,
687-
protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_key(
688-
const_ent));
689-
EXPECT_EQ(
690-
test_int32_2,
691-
protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_value(
692-
const_ent));
693-
694-
const_ent =
669+
msg, &key, &val, &iter));
670+
EXPECT_EQ(test_int32, key);
671+
EXPECT_EQ(test_int32_2, val);
672+
EXPECT_FALSE(
695673
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
696-
msg, &iter);
697-
EXPECT_EQ(nullptr, const_ent);
674+
msg, &key, &val, &iter));
698675
}
699676

700677
TEST(GeneratedCode, Int32Map) {
701678
upb_Arena* arena = upb_Arena_New();
702679
protobuf_test_messages_proto3_TestAllTypesProto3* msg =
703680
protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
704-
const protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry*
705-
const_ent;
706681
size_t iter, count;
707682

708683
check_int32_map_empty(msg);
@@ -751,18 +726,10 @@ TEST(GeneratedCode, Int32Map) {
751726
/* Test iteration */
752727
iter = kUpb_Map_Begin;
753728
count = 0;
754-
755-
while (
756-
(const_ent =
757-
protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
758-
msg, &iter)) != nullptr) {
759-
int32_t key =
760-
protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_key(
761-
const_ent);
762-
int32_t val =
763-
protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_value(
764-
const_ent);
765-
729+
int32_t key;
730+
int32_t val;
731+
while (protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
732+
msg, &key, &val, &iter)) {
766733
count++;
767734
if (key == test_int32) {
768735
EXPECT_EQ(val, test_int32_2);

upb_generator/c/generator.cc

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ std::string MapValueCType(upb::FieldDefPtr map_field) {
225225
return CType(map_field.message_type().map_value());
226226
}
227227

228+
std::string MapValueCTypeConst(upb::FieldDefPtr map_field) {
229+
return CTypeConst(map_field.message_type().map_value());
230+
}
231+
228232
std::string MapKeyValueSize(upb_CType ctype, absl::string_view expr) {
229233
return ctype == kUpb_CType_String || ctype == kUpb_CType_Bytes
230234
? "0"
@@ -486,14 +490,20 @@ void GenerateMapGetters(upb::FieldDefPtr field, const DefPoolPair& pools,
486490
MapValueSize(field, "*val"));
487491
output(
488492
R"cc(
489-
UPB_INLINE $0 $1_$2_next(const $1* msg, size_t* iter) {
490-
const upb_MiniTableField field = $3;
493+
UPB_INLINE bool $0_$1_next(const $0* msg, $2* key, $3* val,
494+
size_t* iter) {
495+
const upb_MiniTableField field = $4;
491496
const upb_Map* map = upb_Message_GetMap(UPB_UPCAST(msg), &field);
492-
if (!map) return NULL;
493-
return ($0)_upb_map_next(map, iter);
497+
if (!map) return false;
498+
upb_MessageValue k;
499+
upb_MessageValue v;
500+
if (!upb_Map_Next(map, &k, &v, iter)) return false;
501+
memcpy(key, &k, sizeof(*key));
502+
memcpy(val, &v, sizeof(*val));
503+
return true;
494504
}
495505
)cc",
496-
CTypeConst(field), msg_name, resolved_name,
506+
msg_name, resolved_name, MapKeyCType(field), MapValueCTypeConst(field),
497507
FieldInitializerStrong(pools, field, options));
498508
// Generate private getter returning a upb_Map or NULL for immutable and
499509
// a upb_Map for mutable.

0 commit comments

Comments
 (0)