@@ -3612,29 +3612,20 @@ void upb_Array_Freeze(upb_Array* arr, const upb_MiniTable* m) {
3612
3612
3613
3613
// Must be last.
3614
3614
3615
- bool upb_Message_NextExtension(const upb_Message* msg,
3616
- const upb_MiniTableExtension** result,
3617
- uintptr_t* iter) {
3618
- size_t count;
3619
- const upb_Extension* ext = UPB_PRIVATE(_upb_Message_Getexts)(msg, &count);
3620
- size_t i = *iter;
3621
- if (i >= count) {
3622
- return false;
3623
- *result = NULL;
3624
- }
3625
- *result = ext[i].ext;
3626
- *iter = i + 1;
3627
- return true;
3615
+ bool upb_Message_NextExtensionReverse(const upb_Message* msg,
3616
+ const upb_MiniTableExtension** result,
3617
+ uintptr_t* iter) {
3618
+ upb_MessageValue val;
3619
+ return UPB_PRIVATE(_upb_Message_NextExtensionReverse)(msg, result, &val,
3620
+ iter);
3628
3621
}
3629
3622
3630
3623
const upb_MiniTableExtension* upb_Message_FindExtensionByNumber(
3631
3624
const upb_Message* msg, uint32_t field_number) {
3632
- size_t count;
3633
- const upb_Extension* ext = UPB_PRIVATE(_upb_Message_Getexts)(msg, &count);
3634
-
3635
- for (; count--; ext++) {
3636
- const upb_MiniTableExtension* e = ext->ext;
3637
- if (upb_MiniTableExtension_Number(e) == field_number) return e;
3625
+ uintptr_t iter = kUpb_Message_ExtensionBegin;
3626
+ const upb_MiniTableExtension* result;
3627
+ while (upb_Message_NextExtensionReverse(msg, &result, &iter)) {
3628
+ if (upb_MiniTableExtension_Number(result) == field_number) return result;
3638
3629
}
3639
3630
return NULL;
3640
3631
}
@@ -3897,14 +3888,15 @@ static int _upb_mapsorter_cmpext(const void* _a, const void* _b) {
3897
3888
return a_num < b_num ? -1 : 1;
3898
3889
}
3899
3890
3900
- bool _upb_mapsorter_pushexts(_upb_mapsorter* s, const upb_Extension* exts ,
3891
+ bool _upb_mapsorter_pushexts(_upb_mapsorter* s, const upb_Message_Internal* in ,
3901
3892
size_t count, _upb_sortedmap* sorted) {
3902
3893
if (!_upb_mapsorter_resize(s, sorted, count)) return false;
3894
+ const upb_Extension* exts =
3895
+ UPB_PTR_AT(in, in->ext_begin, const upb_Extension);
3903
3896
3904
3897
for (size_t i = 0; i < count; i++) {
3905
3898
s->entries[sorted->start + i] = &exts[i];
3906
3899
}
3907
-
3908
3900
qsort(&s->entries[sorted->start], count, sizeof(*s->entries),
3909
3901
_upb_mapsorter_cmpext);
3910
3902
return true;
@@ -3919,8 +3911,6 @@ bool _upb_mapsorter_pushexts(_upb_mapsorter* s, const upb_Extension* exts,
3919
3911
3920
3912
// Must be last.
3921
3913
3922
- static const size_t message_overhead = sizeof(upb_Message_Internal);
3923
-
3924
3914
upb_Message* upb_Message_New(const upb_MiniTable* m, upb_Arena* a) {
3925
3915
return _upb_Message_New(m, a);
3926
3916
}
@@ -3964,39 +3954,14 @@ void _upb_Message_DiscardUnknown_shallow(upb_Message* msg) {
3964
3954
UPB_ASSERT(!upb_Message_IsFrozen(msg));
3965
3955
upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
3966
3956
if (in) {
3967
- in->unknown_end = message_overhead ;
3957
+ in->unknown_end = sizeof(upb_Message_Internal) ;
3968
3958
}
3969
3959
}
3970
3960
3971
- bool upb_Message_NextUnknown(const upb_Message* msg, upb_StringView* data,
3972
- uintptr_t* iter) {
3973
- const upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
3974
- if (in && *iter == kUpb_Message_UnknownBegin) {
3975
- size_t len = in->unknown_end - message_overhead;
3976
- if (len != 0) {
3977
- data->size = len;
3978
- data->data = (const char*)(in + 1);
3979
- (*iter)++;
3980
- return true;
3981
- }
3982
- }
3983
- data->size = 0;
3984
- data->data = NULL;
3985
- return false;
3986
- }
3987
-
3988
- bool upb_Message_HasUnknown(const upb_Message* msg) {
3989
- const upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
3990
- if (in) {
3991
- return in->unknown_end > message_overhead;
3992
- }
3993
- return false;
3994
- }
3995
-
3996
3961
const char* upb_Message_GetUnknown(const upb_Message* msg, size_t* len) {
3997
3962
upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
3998
3963
if (in) {
3999
- *len = in->unknown_end - message_overhead ;
3964
+ *len = in->unknown_end - sizeof(upb_Message_Internal) ;
4000
3965
return (char*)(in + 1);
4001
3966
} else {
4002
3967
*len = 0;
@@ -4074,17 +4039,13 @@ void upb_Message_Freeze(upb_Message* msg, const upb_MiniTable* m) {
4074
4039
}
4075
4040
4076
4041
// Extensions.
4077
- size_t ext_count;
4078
- const upb_Extension* ext = UPB_PRIVATE(_upb_Message_Getexts)(msg, &ext_count);
4079
-
4080
- for (size_t i = 0; i < ext_count; i++) {
4081
- const upb_MiniTableExtension* e = ext[i].ext;
4042
+ uintptr_t iter = kUpb_Message_ExtensionBegin;
4043
+ const upb_MiniTableExtension* e;
4044
+ upb_MessageValue val;
4045
+ while (upb_Message_NextExtension(msg, &e, &val, &iter)) {
4082
4046
const upb_MiniTableField* f = &e->UPB_PRIVATE(field);
4083
4047
const upb_MiniTable* m2 = upb_MiniTableExtension_GetSubMessage(e);
4084
4048
4085
- upb_MessageValue val;
4086
- memcpy(&val, &ext[i].data, sizeof(upb_MessageValue));
4087
-
4088
4049
switch (UPB_PRIVATE(_upb_MiniTableField_Mode)(f)) {
4089
4050
case kUpb_FieldMode_Array: {
4090
4051
upb_Array* arr = (upb_Array*)val.array_val;
@@ -4226,8 +4187,8 @@ static bool _upb_Message_ExtensionsAreEqual(const upb_Message* msg1,
4226
4187
upb_MessageValue val1;
4227
4188
4228
4189
// Iterate over all extensions for msg1, and search msg2 for each extension.
4229
- size_t iter1 = kUpb_Extension_Begin ;
4230
- while (UPB_PRIVATE(_upb_Message_NextExtension)( msg1, m , &e, &val1, &iter1)) {
4190
+ size_t iter1 = kUpb_Message_ExtensionBegin ;
4191
+ while (upb_Message_NextExtension( msg1, &e, &val1, &iter1)) {
4231
4192
const upb_Extension* ext2 = UPB_PRIVATE(_upb_Message_Getext)(msg2, e);
4232
4193
if (!ext2) return false;
4233
4194
@@ -7751,6 +7712,7 @@ const char* upb_DecodeStatus_String(upb_DecodeStatus status) {
7751
7712
#include <setjmp.h>
7752
7713
#include <stdbool.h>
7753
7714
#include <stdint.h>
7715
+ #include <stdlib.h>
7754
7716
#include <string.h>
7755
7717
7756
7718
@@ -8236,32 +8198,33 @@ static void encode_field(upb_encstate* e, const upb_Message* msg,
8236
8198
}
8237
8199
}
8238
8200
8239
- static void encode_msgset_item(upb_encstate* e, const upb_Extension* ext) {
8201
+ static void encode_msgset_item(upb_encstate* e,
8202
+ const upb_MiniTableExtension* ext,
8203
+ const upb_MessageValue ext_val) {
8240
8204
size_t size;
8241
8205
encode_tag(e, kUpb_MsgSet_Item, kUpb_WireType_EndGroup);
8242
- encode_message(e, ext->data .msg_val,
8243
- upb_MiniTableExtension_GetSubMessage(ext->ext), &size);
8206
+ encode_message(e, ext_val .msg_val, upb_MiniTableExtension_GetSubMessage(ext) ,
8207
+ &size);
8244
8208
encode_varint(e, size);
8245
8209
encode_tag(e, kUpb_MsgSet_Message, kUpb_WireType_Delimited);
8246
- encode_varint(e, upb_MiniTableExtension_Number(ext->ext ));
8210
+ encode_varint(e, upb_MiniTableExtension_Number(ext));
8247
8211
encode_tag(e, kUpb_MsgSet_TypeId, kUpb_WireType_Varint);
8248
8212
encode_tag(e, kUpb_MsgSet_Item, kUpb_WireType_StartGroup);
8249
8213
}
8250
8214
8251
- static void encode_ext(upb_encstate* e, const upb_Extension * ext,
8252
- bool is_message_set) {
8215
+ static void encode_ext(upb_encstate* e, const upb_MiniTableExtension * ext,
8216
+ upb_MessageValue ext_val, bool is_message_set) {
8253
8217
if (UPB_UNLIKELY(is_message_set)) {
8254
- encode_msgset_item(e, ext);
8218
+ encode_msgset_item(e, ext, ext_val );
8255
8219
} else {
8256
8220
upb_MiniTableSubInternal sub;
8257
- if (upb_MiniTableField_IsSubMessage(&ext->ext-> UPB_PRIVATE(field))) {
8258
- sub.UPB_PRIVATE(submsg) = &ext->ext-> UPB_PRIVATE(sub).UPB_PRIVATE(submsg);
8221
+ if (upb_MiniTableField_IsSubMessage(&ext->UPB_PRIVATE(field))) {
8222
+ sub.UPB_PRIVATE(submsg) = &ext->UPB_PRIVATE(sub).UPB_PRIVATE(submsg);
8259
8223
} else {
8260
- sub.UPB_PRIVATE(subenum) =
8261
- ext->ext->UPB_PRIVATE(sub).UPB_PRIVATE(subenum);
8224
+ sub.UPB_PRIVATE(subenum) = ext->UPB_PRIVATE(sub).UPB_PRIVATE(subenum);
8262
8225
}
8263
- encode_field(e, &ext->data .UPB_PRIVATE(ext_msg_val), &sub,
8264
- &ext->ext-> UPB_PRIVATE(field));
8226
+ encode_field(e, &ext_val .UPB_PRIVATE(ext_msg_val), &sub,
8227
+ &ext->UPB_PRIVATE(field));
8265
8228
}
8266
8229
}
8267
8230
@@ -8281,7 +8244,7 @@ static void encode_message(upb_encstate* e, const upb_Message* msg,
8281
8244
size_t unknown_size = 0;
8282
8245
uintptr_t iter = kUpb_Message_UnknownBegin;
8283
8246
upb_StringView unknown;
8284
- // Need to write in reverse order, but list is single-linked ; scan to
8247
+ // Need to write in reverse order, but iteration is in-order ; scan to
8285
8248
// reserve capacity up front, then write in-order
8286
8249
while (upb_Message_NextUnknown(msg, &unknown, &iter)) {
8287
8250
unknown_size += unknown.size;
@@ -8298,24 +8261,33 @@ static void encode_message(upb_encstate* e, const upb_Message* msg,
8298
8261
}
8299
8262
8300
8263
if (m->UPB_PRIVATE(ext) != kUpb_ExtMode_NonExtendable) {
8301
- /* Encode all extensions together. Unlike C++, we do not attempt to keep
8302
- * these in field number order relative to normal fields or even to each
8303
- * other. */
8304
- size_t ext_count;
8305
- const upb_Extension* ext =
8306
- UPB_PRIVATE(_upb_Message_Getexts)(msg, &ext_count);
8307
- if (ext_count) {
8308
- if (e->options & kUpb_EncodeOption_Deterministic) {
8309
- _upb_sortedmap sorted;
8310
- _upb_mapsorter_pushexts(&e->sorter, ext, ext_count, &sorted);
8311
- while (_upb_sortedmap_nextext(&e->sorter, &sorted, &ext)) {
8312
- encode_ext(e, ext, m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet);
8313
- }
8314
- _upb_mapsorter_popmap(&e->sorter, &sorted);
8315
- } else {
8316
- const upb_Extension* end = ext + ext_count;
8317
- for (; ext != end; ext++) {
8318
- encode_ext(e, ext, m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet);
8264
+ upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
8265
+ if (in) {
8266
+ /* Encode all extensions together. Unlike C++, we do not attempt to keep
8267
+ * these in field number order relative to normal fields or even to each
8268
+ * other. */
8269
+ size_t ext_count = upb_Message_ExtensionCount(msg);
8270
+ if (ext_count) {
8271
+ if (e->options & kUpb_EncodeOption_Deterministic) {
8272
+ _upb_sortedmap sorted;
8273
+ if (!_upb_mapsorter_pushexts(&e->sorter, in, ext_count, &sorted)) {
8274
+ // TODO: b/378744096 - handle alloc failure
8275
+ }
8276
+ const upb_Extension* ext;
8277
+ while (_upb_sortedmap_nextext(&e->sorter, &sorted, &ext)) {
8278
+ encode_ext(e, ext->ext, ext->data,
8279
+ m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet);
8280
+ }
8281
+ _upb_mapsorter_popmap(&e->sorter, &sorted);
8282
+ } else {
8283
+ const upb_MiniTableExtension* ext;
8284
+ upb_MessageValue ext_val;
8285
+ uintptr_t iter = kUpb_Message_ExtensionBegin;
8286
+ while (UPB_PRIVATE(_upb_Message_NextExtensionReverse)(
8287
+ msg, &ext, &ext_val, &iter)) {
8288
+ encode_ext(e, ext, ext_val,
8289
+ m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet);
8290
+ }
8319
8291
}
8320
8292
}
8321
8293
}
@@ -12393,7 +12365,7 @@ const upb_Extension* UPB_PRIVATE(_upb_Message_Getexts)(
12393
12365
upb_Message_Internal* in = UPB_PRIVATE(_upb_Message_GetInternal)(msg);
12394
12366
if (in) {
12395
12367
*count = (in->size - in->ext_begin) / sizeof(upb_Extension);
12396
- return UPB_PTR_AT(in, in->ext_begin, void );
12368
+ return UPB_PTR_AT(in, in->ext_begin, const upb_Extension );
12397
12369
} else {
12398
12370
*count = 0;
12399
12371
return NULL;
@@ -12542,23 +12514,6 @@ bool UPB_PRIVATE(_upb_Message_NextBaseField)(const upb_Message* msg,
12542
12514
return false;
12543
12515
}
12544
12516
12545
- bool UPB_PRIVATE(_upb_Message_NextExtension)(
12546
- const upb_Message* msg, const upb_MiniTable* m,
12547
- const upb_MiniTableExtension** out_e, upb_MessageValue* out_v,
12548
- size_t* iter) {
12549
- size_t count;
12550
- const upb_Extension* exts = UPB_PRIVATE(_upb_Message_Getexts)(msg, &count);
12551
- size_t i = *iter;
12552
-
12553
- if (++i < count) {
12554
- *out_e = exts[i].ext;
12555
- *out_v = exts[i].data;
12556
- *iter = i;
12557
- return true;
12558
- }
12559
-
12560
- return false;
12561
- }
12562
12517
12563
12518
const char _kUpb_ToBase92[] = {
12564
12519
' ', '!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-', '.', '/',
0 commit comments