google-protobuf 3.22.5-x86-linux → 3.23.0.rc.1-x86-linux

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of google-protobuf might be problematic. Click here for more details.

@@ -166,9 +166,18 @@
166
166
  #define UPB_LONGJMP(buf, val) longjmp(buf, val)
167
167
  #endif
168
168
 
169
+ #ifdef __GNUC__
170
+ #define UPB_USE_C11_ATOMICS
171
+ #define UPB_ATOMIC(T) _Atomic(T)
172
+ #else
173
+ #define UPB_ATOMIC(T) T
174
+ #endif
175
+
169
176
  /* UPB_PTRADD(ptr, ofs): add pointer while avoiding "NULL + 0" UB */
170
177
  #define UPB_PTRADD(ptr, ofs) ((ofs) ? (ptr) + (ofs) : (ptr))
171
178
 
179
+ #define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only
180
+
172
181
  /* Configure whether fasttable is switched on or not. *************************/
173
182
 
174
183
  #ifdef __has_attribute
@@ -390,6 +399,7 @@ void upb_Array_Set(upb_Array* arr, size_t i, upb_MessageValue val) {
390
399
  }
391
400
 
392
401
  bool upb_Array_Append(upb_Array* arr, upb_MessageValue val, upb_Arena* arena) {
402
+ UPB_ASSERT(arena);
393
403
  if (!upb_Array_Resize(arr, arr->size + 1, arena)) {
394
404
  return false;
395
405
  }
@@ -406,6 +416,7 @@ void upb_Array_Move(upb_Array* arr, size_t dst_idx, size_t src_idx,
406
416
 
407
417
  bool upb_Array_Insert(upb_Array* arr, size_t i, size_t count,
408
418
  upb_Arena* arena) {
419
+ UPB_ASSERT(arena);
409
420
  UPB_ASSERT(i <= arr->size);
410
421
  UPB_ASSERT(count + arr->size >= count);
411
422
  const size_t oldsize = arr->size;
@@ -500,6 +511,7 @@ void upb_Map_Clear(upb_Map* map) { _upb_Map_Clear(map); }
500
511
 
501
512
  upb_MapInsertStatus upb_Map_Insert(upb_Map* map, upb_MessageValue key,
502
513
  upb_MessageValue val, upb_Arena* arena) {
514
+ UPB_ASSERT(arena);
503
515
  return (upb_MapInsertStatus)_upb_Map_Insert(map, &key, map->key_size, &val,
504
516
  map->val_size, arena);
505
517
  }
@@ -764,9 +776,9 @@ const upb_MiniTable google_protobuf_FileDescriptorProto_msg_init = {
764
776
  UPB_SIZE(72, 144), 13, kUpb_ExtMode_NonExtendable, 13, UPB_FASTTABLE_MASK(120), 0,
765
777
  UPB_FASTTABLE_INIT({
766
778
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
767
- {0x000800000100000a, &upb_psb_1bt},
768
- {0x0018000002000012, &upb_psb_1bt},
769
- {0x002800003f00001a, &upb_prb_1bt},
779
+ {0x000800000100000a, &upb_pss_1bt},
780
+ {0x0018000002000012, &upb_pss_1bt},
781
+ {0x002800003f00001a, &upb_prs_1bt},
770
782
  {0x003000003f000022, &upb_prm_1bt_max128b},
771
783
  {0x003800003f01002a, &upb_prm_1bt_max64b},
772
784
  {0x004000003f020032, &upb_prm_1bt_max64b},
@@ -775,8 +787,8 @@ const upb_MiniTable google_protobuf_FileDescriptorProto_msg_init = {
775
787
  {0x005800000405004a, &upb_psm_1bt_max64b},
776
788
  {0x006000003f000050, &upb_prv4_1bt},
777
789
  {0x006800003f000058, &upb_prv4_1bt},
778
- {0x0070000005000062, &upb_psb_1bt},
779
- {0x008000000600006a, &upb_psb_1bt},
790
+ {0x0070000005000062, &upb_pss_1bt},
791
+ {0x008000000600006a, &upb_pss_1bt},
780
792
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
781
793
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
782
794
  })
@@ -812,7 +824,7 @@ const upb_MiniTable google_protobuf_DescriptorProto_msg_init = {
812
824
  UPB_SIZE(48, 96), 10, kUpb_ExtMode_NonExtendable, 10, UPB_FASTTABLE_MASK(120), 0,
813
825
  UPB_FASTTABLE_INIT({
814
826
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
815
- {0x000800000100000a, &upb_psb_1bt},
827
+ {0x000800000100000a, &upb_pss_1bt},
816
828
  {0x001800003f000012, &upb_prm_1bt_max128b},
817
829
  {0x002000003f01001a, &upb_prm_1bt_max128b},
818
830
  {0x002800003f020022, &upb_prm_1bt_max64b},
@@ -821,7 +833,7 @@ const upb_MiniTable google_protobuf_DescriptorProto_msg_init = {
821
833
  {0x004000000205003a, &upb_psm_1bt_max64b},
822
834
  {0x004800003f060042, &upb_prm_1bt_max64b},
823
835
  {0x005000003f07004a, &upb_prm_1bt_max64b},
824
- {0x005800003f000052, &upb_prb_1bt},
836
+ {0x005800003f000052, &upb_prs_1bt},
825
837
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
826
838
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
827
839
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@@ -869,21 +881,26 @@ const upb_MiniTable google_protobuf_DescriptorProto_ReservedRange_msg_init = {
869
881
  })
870
882
  };
871
883
 
872
- static const upb_MiniTableSub google_protobuf_ExtensionRangeOptions_submsgs[1] = {
884
+ static const upb_MiniTableSub google_protobuf_ExtensionRangeOptions_submsgs[3] = {
885
+ {.submsg = &google_protobuf_ExtensionRangeOptions_Declaration_msg_init},
886
+ {.subenum = &google_protobuf_ExtensionRangeOptions_VerificationState_enum_init},
873
887
  {.submsg = &google_protobuf_UninterpretedOption_msg_init},
874
888
  };
875
889
 
876
- static const upb_MiniTableField google_protobuf_ExtensionRangeOptions__fields[1] = {
877
- {999, 0, 0, 0, 11, kUpb_FieldMode_Array | (UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
890
+ static const upb_MiniTableField google_protobuf_ExtensionRangeOptions__fields[3] = {
891
+ {2, UPB_SIZE(4, 8), 0, 0, 11, kUpb_FieldMode_Array | (UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
892
+ {3, UPB_SIZE(8, 4), 1, 1, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
893
+ {999, UPB_SIZE(12, 16), 0, 2, 11, kUpb_FieldMode_Array | (UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
878
894
  };
879
895
 
880
896
  const upb_MiniTable google_protobuf_ExtensionRangeOptions_msg_init = {
881
897
  &google_protobuf_ExtensionRangeOptions_submsgs[0],
882
898
  &google_protobuf_ExtensionRangeOptions__fields[0],
883
- 8, 1, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(248), 0,
899
+ UPB_SIZE(16, 24), 3, kUpb_ExtMode_Extendable, 0, UPB_FASTTABLE_MASK(248), 0,
884
900
  UPB_FASTTABLE_INIT({
885
901
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
886
902
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
903
+ {0x000800003f000012, &upb_prm_1bt_max64b},
887
904
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
888
905
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
889
906
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@@ -904,8 +921,8 @@ const upb_MiniTable google_protobuf_ExtensionRangeOptions_msg_init = {
904
921
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
905
922
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
906
923
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
924
+ {0x001000003f023eba, &upb_prm_2bt_max128b},
907
925
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
908
- {0x000000003f003eba, &upb_prm_2bt_max128b},
909
926
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
910
927
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
911
928
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@@ -913,6 +930,30 @@ const upb_MiniTable google_protobuf_ExtensionRangeOptions_msg_init = {
913
930
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
914
931
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
915
932
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
933
+ })
934
+ };
935
+
936
+ static const upb_MiniTableField google_protobuf_ExtensionRangeOptions_Declaration__fields[6] = {
937
+ {1, 4, 1, kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
938
+ {2, UPB_SIZE(12, 16), 2, kUpb_NoSub, 12, kUpb_FieldMode_Scalar | kUpb_LabelFlags_IsAlternate | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
939
+ {3, UPB_SIZE(20, 32), 3, kUpb_NoSub, 12, kUpb_FieldMode_Scalar | kUpb_LabelFlags_IsAlternate | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
940
+ {4, 8, 4, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
941
+ {5, 9, 5, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
942
+ {6, 10, 6, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
943
+ };
944
+
945
+ const upb_MiniTable google_protobuf_ExtensionRangeOptions_Declaration_msg_init = {
946
+ NULL,
947
+ &google_protobuf_ExtensionRangeOptions_Declaration__fields[0],
948
+ UPB_SIZE(32, 48), 6, kUpb_ExtMode_NonExtendable, 6, UPB_FASTTABLE_MASK(56), 0,
949
+ UPB_FASTTABLE_INIT({
950
+ {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
951
+ {0x0004000001000008, &upb_psv4_1bt},
952
+ {0x0010000002000012, &upb_pss_1bt},
953
+ {0x002000000300001a, &upb_pss_1bt},
954
+ {0x0008000004000020, &upb_psb1_1bt},
955
+ {0x0009000005000028, &upb_psb1_1bt},
956
+ {0x000a000006000030, &upb_psb1_1bt},
916
957
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
917
958
  })
918
959
  };
@@ -943,16 +984,16 @@ const upb_MiniTable google_protobuf_FieldDescriptorProto_msg_init = {
943
984
  UPB_SIZE(72, 112), 11, kUpb_ExtMode_NonExtendable, 10, UPB_FASTTABLE_MASK(248), 0,
944
985
  UPB_FASTTABLE_INIT({
945
986
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
946
- {0x001800000100000a, &upb_psb_1bt},
947
- {0x0028000002000012, &upb_psb_1bt},
987
+ {0x001800000100000a, &upb_pss_1bt},
988
+ {0x0028000002000012, &upb_pss_1bt},
948
989
  {0x0004000003000018, &upb_psv4_1bt},
949
990
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
950
991
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
951
- {0x0038000006000032, &upb_psb_1bt},
952
- {0x004800000700003a, &upb_psb_1bt},
992
+ {0x0038000006000032, &upb_pss_1bt},
993
+ {0x004800000700003a, &upb_pss_1bt},
953
994
  {0x0058000008020042, &upb_psm_1bt_max64b},
954
995
  {0x0010000009000048, &upb_psv4_1bt},
955
- {0x006000000a000052, &upb_psb_1bt},
996
+ {0x006000000a000052, &upb_pss_1bt},
956
997
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
957
998
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
958
999
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@@ -992,7 +1033,7 @@ const upb_MiniTable google_protobuf_OneofDescriptorProto_msg_init = {
992
1033
  UPB_SIZE(16, 32), 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(24), 0,
993
1034
  UPB_FASTTABLE_INIT({
994
1035
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
995
- {0x000800000100000a, &upb_psb_1bt},
1036
+ {0x000800000100000a, &upb_pss_1bt},
996
1037
  {0x0018000002000012, &upb_psm_1bt_max64b},
997
1038
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
998
1039
  })
@@ -1018,11 +1059,11 @@ const upb_MiniTable google_protobuf_EnumDescriptorProto_msg_init = {
1018
1059
  UPB_SIZE(32, 56), 5, kUpb_ExtMode_NonExtendable, 5, UPB_FASTTABLE_MASK(56), 0,
1019
1060
  UPB_FASTTABLE_INIT({
1020
1061
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1021
- {0x000800000100000a, &upb_psb_1bt},
1062
+ {0x000800000100000a, &upb_pss_1bt},
1022
1063
  {0x001800003f000012, &upb_prm_1bt_max64b},
1023
1064
  {0x002000000201001a, &upb_psm_1bt_max64b},
1024
1065
  {0x002800003f020022, &upb_prm_1bt_max64b},
1025
- {0x003000003f00002a, &upb_prb_1bt},
1066
+ {0x003000003f00002a, &upb_prs_1bt},
1026
1067
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1027
1068
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1028
1069
  })
@@ -1061,7 +1102,7 @@ const upb_MiniTable google_protobuf_EnumValueDescriptorProto_msg_init = {
1061
1102
  UPB_SIZE(24, 32), 3, kUpb_ExtMode_NonExtendable, 3, UPB_FASTTABLE_MASK(24), 0,
1062
1103
  UPB_FASTTABLE_INIT({
1063
1104
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1064
- {0x000800000100000a, &upb_psb_1bt},
1105
+ {0x000800000100000a, &upb_pss_1bt},
1065
1106
  {0x0004000002000010, &upb_psv4_1bt},
1066
1107
  {0x001800000300001a, &upb_psm_1bt_max64b},
1067
1108
  })
@@ -1084,7 +1125,7 @@ const upb_MiniTable google_protobuf_ServiceDescriptorProto_msg_init = {
1084
1125
  UPB_SIZE(24, 40), 3, kUpb_ExtMode_NonExtendable, 3, UPB_FASTTABLE_MASK(24), 0,
1085
1126
  UPB_FASTTABLE_INIT({
1086
1127
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1087
- {0x000800000100000a, &upb_psb_1bt},
1128
+ {0x000800000100000a, &upb_pss_1bt},
1088
1129
  {0x001800003f000012, &upb_prm_1bt_max128b},
1089
1130
  {0x002000000201001a, &upb_psm_1bt_max64b},
1090
1131
  })
@@ -1109,9 +1150,9 @@ const upb_MiniTable google_protobuf_MethodDescriptorProto_msg_init = {
1109
1150
  UPB_SIZE(40, 64), 6, kUpb_ExtMode_NonExtendable, 6, UPB_FASTTABLE_MASK(56), 0,
1110
1151
  UPB_FASTTABLE_INIT({
1111
1152
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1112
- {0x000800000100000a, &upb_psb_1bt},
1113
- {0x0018000002000012, &upb_psb_1bt},
1114
- {0x002800000300001a, &upb_psb_1bt},
1153
+ {0x000800000100000a, &upb_pss_1bt},
1154
+ {0x0018000002000012, &upb_pss_1bt},
1155
+ {0x002800000300001a, &upb_pss_1bt},
1115
1156
  {0x0038000004000022, &upb_psm_1bt_max64b},
1116
1157
  {0x0001000005000028, &upb_psb1_1bt},
1117
1158
  {0x0002000006000030, &upb_psb1_1bt},
@@ -1154,17 +1195,17 @@ const upb_MiniTable google_protobuf_FileOptions_msg_init = {
1154
1195
  UPB_SIZE(104, 192), 21, kUpb_ExtMode_Extendable, 1, UPB_FASTTABLE_MASK(248), 0,
1155
1196
  UPB_FASTTABLE_INIT({
1156
1197
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1157
- {0x001800000100000a, &upb_psb_1bt},
1198
+ {0x001800000100000a, &upb_pss_1bt},
1158
1199
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1159
1200
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1160
1201
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1161
1202
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1162
1203
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1163
1204
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1164
- {0x0028000002000042, &upb_psb_1bt},
1205
+ {0x0028000002000042, &upb_pss_1bt},
1165
1206
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1166
1207
  {0x0008000004000050, &upb_psb1_1bt},
1167
- {0x003800000500005a, &upb_psb_1bt},
1208
+ {0x003800000500005a, &upb_pss_1bt},
1168
1209
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1169
1210
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1170
1211
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@@ -1174,15 +1215,15 @@ const upb_MiniTable google_protobuf_FileOptions_msg_init = {
1174
1215
  {0x000b000008000190, &upb_psb1_2bt},
1175
1216
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1176
1217
  {0x000c0000090001a0, &upb_psb1_2bt},
1177
- {0x005800000e0002aa, &upb_psb_2bt},
1218
+ {0x005800000e0002aa, &upb_pss_2bt},
1178
1219
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1179
1220
  {0x000d00000a0001b8, &upb_psb1_2bt},
1180
- {0x00780000100002c2, &upb_psb_2bt},
1181
- {0x00880000110002ca, &upb_psb_2bt},
1221
+ {0x00780000100002c2, &upb_pss_2bt},
1222
+ {0x00880000110002ca, &upb_pss_2bt},
1182
1223
  {0x00100000120002d0, &upb_psb1_2bt},
1183
1224
  {0x000e00000b0001d8, &upb_psb1_2bt},
1184
- {0x00980000130002e2, &upb_psb_2bt},
1185
- {0x00a80000140002ea, &upb_psb_2bt},
1225
+ {0x00980000130002e2, &upb_pss_2bt},
1226
+ {0x00a80000140002ea, &upb_pss_2bt},
1186
1227
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1187
1228
  {0x000f00000c0001f8, &upb_psb1_2bt},
1188
1229
  })
@@ -1241,15 +1282,16 @@ const upb_MiniTable google_protobuf_MessageOptions_msg_init = {
1241
1282
  })
1242
1283
  };
1243
1284
 
1244
- static const upb_MiniTableSub google_protobuf_FieldOptions_submsgs[5] = {
1285
+ static const upb_MiniTableSub google_protobuf_FieldOptions_submsgs[6] = {
1245
1286
  {.subenum = &google_protobuf_FieldOptions_CType_enum_init},
1246
1287
  {.subenum = &google_protobuf_FieldOptions_JSType_enum_init},
1247
1288
  {.subenum = &google_protobuf_FieldOptions_OptionRetention_enum_init},
1248
1289
  {.subenum = &google_protobuf_FieldOptions_OptionTargetType_enum_init},
1290
+ {.subenum = &google_protobuf_FieldOptions_OptionTargetType_enum_init},
1249
1291
  {.submsg = &google_protobuf_UninterpretedOption_msg_init},
1250
1292
  };
1251
1293
 
1252
- static const upb_MiniTableField google_protobuf_FieldOptions__fields[11] = {
1294
+ static const upb_MiniTableField google_protobuf_FieldOptions__fields[12] = {
1253
1295
  {1, 4, 1, 0, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
1254
1296
  {2, 8, 2, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
1255
1297
  {3, 9, 3, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
@@ -1260,13 +1302,14 @@ static const upb_MiniTableField google_protobuf_FieldOptions__fields[11] = {
1260
1302
  {16, 18, 8, kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
1261
1303
  {17, 20, 9, 2, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
1262
1304
  {18, 24, 10, 3, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
1263
- {999, UPB_SIZE(28, 32), 0, 4, 11, kUpb_FieldMode_Array | (UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
1305
+ {19, UPB_SIZE(28, 32), 0, 4, 14, kUpb_FieldMode_Array | (UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
1306
+ {999, UPB_SIZE(32, 40), 0, 5, 11, kUpb_FieldMode_Array | (UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte) << kUpb_FieldRep_Shift)},
1264
1307
  };
1265
1308
 
1266
1309
  const upb_MiniTable google_protobuf_FieldOptions_msg_init = {
1267
1310
  &google_protobuf_FieldOptions_submsgs[0],
1268
1311
  &google_protobuf_FieldOptions__fields[0],
1269
- UPB_SIZE(32, 40), 11, kUpb_ExtMode_Extendable, 3, UPB_FASTTABLE_MASK(248), 0,
1312
+ UPB_SIZE(40, 48), 12, kUpb_ExtMode_Extendable, 3, UPB_FASTTABLE_MASK(248), 0,
1270
1313
  UPB_FASTTABLE_INIT({
1271
1314
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1272
1315
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@@ -1291,7 +1334,7 @@ const upb_MiniTable google_protobuf_FieldOptions_msg_init = {
1291
1334
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1292
1335
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1293
1336
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1294
- {0x002000003f043eba, &upb_prm_2bt_max128b},
1337
+ {0x002800003f053eba, &upb_prm_2bt_max128b},
1295
1338
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1296
1339
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1297
1340
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@@ -1573,12 +1616,12 @@ const upb_MiniTable google_protobuf_UninterpretedOption_msg_init = {
1573
1616
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1574
1617
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1575
1618
  {0x000800003f000012, &upb_prm_1bt_max64b},
1576
- {0x001000000100001a, &upb_psb_1bt},
1619
+ {0x001000000100001a, &upb_pss_1bt},
1577
1620
  {0x0020000002000020, &upb_psv8_1bt},
1578
1621
  {0x0028000003000028, &upb_psv8_1bt},
1579
1622
  {0x0030000004000031, &upb_psf8_1bt},
1580
1623
  {0x003800000500003a, &upb_psb_1bt},
1581
- {0x0048000006000042, &upb_psb_1bt},
1624
+ {0x0048000006000042, &upb_pss_1bt},
1582
1625
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1583
1626
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1584
1627
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@@ -1600,7 +1643,7 @@ const upb_MiniTable google_protobuf_UninterpretedOption_NamePart_msg_init = {
1600
1643
  UPB_SIZE(16, 24), 2, kUpb_ExtMode_NonExtendable, 2, UPB_FASTTABLE_MASK(24), 2,
1601
1644
  UPB_FASTTABLE_INIT({
1602
1645
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1603
- {0x000800000100000a, &upb_psb_1bt},
1646
+ {0x000800000100000a, &upb_pss_1bt},
1604
1647
  {0x0001000002000010, &upb_psb1_1bt},
1605
1648
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1606
1649
  })
@@ -1640,10 +1683,10 @@ const upb_MiniTable google_protobuf_SourceCodeInfo_Location_msg_init = {
1640
1683
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1641
1684
  {0x000800003f00000a, &upb_ppv4_1bt},
1642
1685
  {0x001000003f000012, &upb_ppv4_1bt},
1643
- {0x001800000100001a, &upb_psb_1bt},
1644
- {0x0028000002000022, &upb_psb_1bt},
1686
+ {0x001800000100001a, &upb_pss_1bt},
1687
+ {0x0028000002000022, &upb_pss_1bt},
1645
1688
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1646
- {0x003800003f000032, &upb_prb_1bt},
1689
+ {0x003800003f000032, &upb_prs_1bt},
1647
1690
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1648
1691
  })
1649
1692
  };
@@ -1685,7 +1728,7 @@ const upb_MiniTable google_protobuf_GeneratedCodeInfo_Annotation_msg_init = {
1685
1728
  UPB_FASTTABLE_INIT({
1686
1729
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
1687
1730
  {0x001000003f00000a, &upb_ppv4_1bt},
1688
- {0x0018000001000012, &upb_psb_1bt},
1731
+ {0x0018000001000012, &upb_pss_1bt},
1689
1732
  {0x0004000002000018, &upb_psv4_1bt},
1690
1733
  {0x0008000003000020, &upb_psv4_1bt},
1691
1734
  {0x0000000000000000, &_upb_FastDecoder_DecodeGeneric},
@@ -1694,13 +1737,14 @@ const upb_MiniTable google_protobuf_GeneratedCodeInfo_Annotation_msg_init = {
1694
1737
  })
1695
1738
  };
1696
1739
 
1697
- static const upb_MiniTable *messages_layout[27] = {
1740
+ static const upb_MiniTable *messages_layout[28] = {
1698
1741
  &google_protobuf_FileDescriptorSet_msg_init,
1699
1742
  &google_protobuf_FileDescriptorProto_msg_init,
1700
1743
  &google_protobuf_DescriptorProto_msg_init,
1701
1744
  &google_protobuf_DescriptorProto_ExtensionRange_msg_init,
1702
1745
  &google_protobuf_DescriptorProto_ReservedRange_msg_init,
1703
1746
  &google_protobuf_ExtensionRangeOptions_msg_init,
1747
+ &google_protobuf_ExtensionRangeOptions_Declaration_msg_init,
1704
1748
  &google_protobuf_FieldDescriptorProto_msg_init,
1705
1749
  &google_protobuf_OneofDescriptorProto_msg_init,
1706
1750
  &google_protobuf_EnumDescriptorProto_msg_init,
@@ -1724,6 +1768,15 @@ static const upb_MiniTable *messages_layout[27] = {
1724
1768
  &google_protobuf_GeneratedCodeInfo_Annotation_msg_init,
1725
1769
  };
1726
1770
 
1771
+ const upb_MiniTableEnum google_protobuf_ExtensionRangeOptions_VerificationState_enum_init = {
1772
+ 64,
1773
+ 0,
1774
+ {
1775
+ 0x3,
1776
+ 0x0,
1777
+ },
1778
+ };
1779
+
1727
1780
  const upb_MiniTableEnum google_protobuf_FieldDescriptorProto_Label_enum_init = {
1728
1781
  64,
1729
1782
  0,
@@ -1805,7 +1858,8 @@ const upb_MiniTableEnum google_protobuf_MethodOptions_IdempotencyLevel_enum_init
1805
1858
  },
1806
1859
  };
1807
1860
 
1808
- static const upb_MiniTableEnum *enums_layout[9] = {
1861
+ static const upb_MiniTableEnum *enums_layout[10] = {
1862
+ &google_protobuf_ExtensionRangeOptions_VerificationState_enum_init,
1809
1863
  &google_protobuf_FieldDescriptorProto_Label_enum_init,
1810
1864
  &google_protobuf_FieldDescriptorProto_Type_enum_init,
1811
1865
  &google_protobuf_FieldOptions_CType_enum_init,
@@ -1821,8 +1875,8 @@ const upb_MiniTableFile google_protobuf_descriptor_proto_upb_file_layout = {
1821
1875
  messages_layout,
1822
1876
  enums_layout,
1823
1877
  NULL,
1824
- 27,
1825
- 9,
1878
+ 28,
1879
+ 10,
1826
1880
  0,
1827
1881
  };
1828
1882
 
@@ -2587,7 +2641,7 @@ bool upb_inttable_next(const upb_inttable* t, uintptr_t* key, upb_value* val,
2587
2641
  intptr_t* iter) {
2588
2642
  intptr_t i = *iter;
2589
2643
  if ((size_t)(i + 1) <= t->array_size) {
2590
- while (++i < t->array_size) {
2644
+ while ((size_t)++i < t->array_size) {
2591
2645
  upb_tabval ent = t->array[i];
2592
2646
  if (upb_arrhas(ent)) {
2593
2647
  *key = i;
@@ -2613,7 +2667,7 @@ bool upb_inttable_next(const upb_inttable* t, uintptr_t* key, upb_value* val,
2613
2667
 
2614
2668
  void upb_inttable_removeiter(upb_inttable* t, intptr_t* iter) {
2615
2669
  intptr_t i = *iter;
2616
- if (i < t->array_size) {
2670
+ if ((size_t)i < t->array_size) {
2617
2671
  t->array_count--;
2618
2672
  mutable_array(t)[i].val = -1;
2619
2673
  } else {
@@ -5092,107 +5146,127 @@ upb_alloc upb_alloc_global = {&upb_global_allocfunc};
5092
5146
 
5093
5147
  // Must be last.
5094
5148
 
5095
- static uint32_t* upb_cleanup_pointer(uintptr_t cleanup_metadata) {
5096
- return (uint32_t*)(cleanup_metadata & ~0x1);
5097
- }
5098
-
5099
- static bool upb_cleanup_has_initial_block(uintptr_t cleanup_metadata) {
5100
- return cleanup_metadata & 0x1;
5101
- }
5102
-
5103
- static uintptr_t upb_cleanup_metadata(uint32_t* cleanup,
5104
- bool has_initial_block) {
5105
- return (uintptr_t)cleanup | has_initial_block;
5106
- }
5107
-
5108
5149
  struct _upb_MemBlock {
5109
- struct _upb_MemBlock* next;
5150
+ // Atomic only for the benefit of SpaceAllocated().
5151
+ UPB_ATOMIC(_upb_MemBlock*) next;
5110
5152
  uint32_t size;
5111
- uint32_t cleanups;
5112
5153
  // Data follows.
5113
5154
  };
5114
5155
 
5115
- typedef struct cleanup_ent {
5116
- upb_CleanupFunc* cleanup;
5117
- void* ud;
5118
- } cleanup_ent;
5119
-
5120
5156
  static const size_t memblock_reserve =
5121
5157
  UPB_ALIGN_UP(sizeof(_upb_MemBlock), UPB_MALLOC_ALIGN);
5122
5158
 
5123
- static upb_Arena* arena_findroot(upb_Arena* a) {
5124
- /* Path splitting keeps time complexity down, see:
5125
- * https://en.wikipedia.org/wiki/Disjoint-set_data_structure */
5126
- while (a->parent != a) {
5127
- upb_Arena* next = a->parent;
5128
- a->parent = next->parent;
5159
+ typedef struct _upb_ArenaRoot {
5160
+ upb_Arena* root;
5161
+ uintptr_t tagged_count;
5162
+ } _upb_ArenaRoot;
5163
+
5164
+ static _upb_ArenaRoot _upb_Arena_FindRoot(upb_Arena* a) {
5165
+ uintptr_t poc = upb_Atomic_Load(&a->parent_or_count, memory_order_acquire);
5166
+ while (_upb_Arena_IsTaggedPointer(poc)) {
5167
+ upb_Arena* next = _upb_Arena_PointerFromTagged(poc);
5168
+ UPB_ASSERT(a != next);
5169
+ uintptr_t next_poc =
5170
+ upb_Atomic_Load(&next->parent_or_count, memory_order_acquire);
5171
+
5172
+ if (_upb_Arena_IsTaggedPointer(next_poc)) {
5173
+ // To keep complexity down, we lazily collapse levels of the tree. This
5174
+ // keeps it flat in the final case, but doesn't cost much incrementally.
5175
+ //
5176
+ // Path splitting keeps time complexity down, see:
5177
+ // https://en.wikipedia.org/wiki/Disjoint-set_data_structure
5178
+ //
5179
+ // We can safely use a relaxed atomic here because all threads doing this
5180
+ // will converge on the same value and we don't need memory orderings to
5181
+ // be visible.
5182
+ //
5183
+ // This is true because:
5184
+ // - If no fuses occur, this will eventually become the root.
5185
+ // - If fuses are actively occuring, the root may change, but the
5186
+ // invariant is that `parent_or_count` merely points to *a* parent.
5187
+ //
5188
+ // In other words, it is moving towards "the" root, and that root may move
5189
+ // further away over time, but the path towards that root will continue to
5190
+ // be valid and the creation of the path carries all the memory orderings
5191
+ // required.
5192
+ UPB_ASSERT(a != _upb_Arena_PointerFromTagged(next_poc));
5193
+ upb_Atomic_Store(&a->parent_or_count, next_poc, memory_order_relaxed);
5194
+ }
5129
5195
  a = next;
5196
+ poc = next_poc;
5130
5197
  }
5131
- return a;
5198
+ return (_upb_ArenaRoot){.root = a, .tagged_count = poc};
5132
5199
  }
5133
5200
 
5134
5201
  size_t upb_Arena_SpaceAllocated(upb_Arena* arena) {
5135
- arena = arena_findroot(arena);
5202
+ arena = _upb_Arena_FindRoot(arena).root;
5136
5203
  size_t memsize = 0;
5137
5204
 
5138
- _upb_MemBlock* block = arena->freelist;
5139
-
5140
- while (block) {
5141
- memsize += sizeof(_upb_MemBlock) + block->size;
5142
- block = block->next;
5205
+ while (arena != NULL) {
5206
+ _upb_MemBlock* block =
5207
+ upb_Atomic_Load(&arena->blocks, memory_order_relaxed);
5208
+ while (block != NULL) {
5209
+ memsize += sizeof(_upb_MemBlock) + block->size;
5210
+ block = upb_Atomic_Load(&block->next, memory_order_relaxed);
5211
+ }
5212
+ arena = upb_Atomic_Load(&arena->next, memory_order_relaxed);
5143
5213
  }
5144
5214
 
5145
5215
  return memsize;
5146
5216
  }
5147
5217
 
5148
- uint32_t upb_Arena_DebugRefCount(upb_Arena* arena) {
5149
- return arena_findroot(arena)->refcount;
5218
+ uint32_t upb_Arena_DebugRefCount(upb_Arena* a) {
5219
+ // These loads could probably be relaxed, but given that this is debug-only,
5220
+ // it's not worth introducing a new variant for it.
5221
+ uintptr_t poc = upb_Atomic_Load(&a->parent_or_count, memory_order_acquire);
5222
+ while (_upb_Arena_IsTaggedPointer(poc)) {
5223
+ a = _upb_Arena_PointerFromTagged(poc);
5224
+ poc = upb_Atomic_Load(&a->parent_or_count, memory_order_acquire);
5225
+ }
5226
+ return _upb_Arena_RefCountFromTagged(poc);
5150
5227
  }
5151
5228
 
5152
- static void upb_Arena_addblock(upb_Arena* a, upb_Arena* root, void* ptr,
5153
- size_t size) {
5229
+ static void upb_Arena_AddBlock(upb_Arena* a, void* ptr, size_t size) {
5154
5230
  _upb_MemBlock* block = ptr;
5155
5231
 
5156
- /* The block is for arena |a|, but should appear in the freelist of |root|. */
5157
- block->next = root->freelist;
5232
+ // Insert into linked list.
5158
5233
  block->size = (uint32_t)size;
5159
- block->cleanups = 0;
5160
- root->freelist = block;
5161
- a->last_size = block->size;
5162
- if (!root->freelist_tail) root->freelist_tail = block;
5234
+ upb_Atomic_Init(&block->next, a->blocks);
5235
+ upb_Atomic_Store(&a->blocks, block, memory_order_release);
5163
5236
 
5164
5237
  a->head.ptr = UPB_PTR_AT(block, memblock_reserve, char);
5165
5238
  a->head.end = UPB_PTR_AT(block, size, char);
5166
- a->cleanup_metadata = upb_cleanup_metadata(
5167
- &block->cleanups, upb_cleanup_has_initial_block(a->cleanup_metadata));
5168
5239
 
5169
5240
  UPB_POISON_MEMORY_REGION(a->head.ptr, a->head.end - a->head.ptr);
5170
5241
  }
5171
5242
 
5172
- static bool upb_Arena_Allocblock(upb_Arena* a, size_t size) {
5173
- upb_Arena* root = arena_findroot(a);
5174
- size_t block_size = UPB_MAX(size, a->last_size * 2) + memblock_reserve;
5175
- _upb_MemBlock* block = upb_malloc(root->block_alloc, block_size);
5243
+ static bool upb_Arena_AllocBlock(upb_Arena* a, size_t size) {
5244
+ if (!a->block_alloc) return false;
5245
+ _upb_MemBlock* last_block = upb_Atomic_Load(&a->blocks, memory_order_acquire);
5246
+ size_t last_size = last_block != NULL ? last_block->size : 128;
5247
+ size_t block_size = UPB_MAX(size, last_size * 2) + memblock_reserve;
5248
+ _upb_MemBlock* block = upb_malloc(upb_Arena_BlockAlloc(a), block_size);
5176
5249
 
5177
5250
  if (!block) return false;
5178
- upb_Arena_addblock(a, root, block, block_size);
5251
+ upb_Arena_AddBlock(a, block, block_size);
5179
5252
  return true;
5180
5253
  }
5181
5254
 
5182
5255
  void* _upb_Arena_SlowMalloc(upb_Arena* a, size_t size) {
5183
- if (!upb_Arena_Allocblock(a, size)) return NULL; /* Out of memory. */
5256
+ if (!upb_Arena_AllocBlock(a, size)) return NULL; /* Out of memory. */
5184
5257
  UPB_ASSERT(_upb_ArenaHas(a) >= size);
5185
5258
  return upb_Arena_Malloc(a, size);
5186
5259
  }
5187
5260
 
5188
5261
  /* Public Arena API ***********************************************************/
5189
5262
 
5190
- static upb_Arena* arena_initslow(void* mem, size_t n, upb_alloc* alloc) {
5263
+ static upb_Arena* upb_Arena_InitSlow(upb_alloc* alloc) {
5191
5264
  const size_t first_block_overhead = sizeof(upb_Arena) + memblock_reserve;
5192
5265
  upb_Arena* a;
5193
5266
 
5194
5267
  /* We need to malloc the initial block. */
5195
- n = first_block_overhead + 256;
5268
+ char* mem;
5269
+ size_t n = first_block_overhead + 256;
5196
5270
  if (!alloc || !(mem = upb_malloc(alloc, n))) {
5197
5271
  return NULL;
5198
5272
  }
@@ -5200,14 +5274,13 @@ static upb_Arena* arena_initslow(void* mem, size_t n, upb_alloc* alloc) {
5200
5274
  a = UPB_PTR_AT(mem, n - sizeof(*a), upb_Arena);
5201
5275
  n -= sizeof(*a);
5202
5276
 
5203
- a->block_alloc = alloc;
5204
- a->parent = a;
5205
- a->refcount = 1;
5206
- a->freelist = NULL;
5207
- a->freelist_tail = NULL;
5208
- a->cleanup_metadata = upb_cleanup_metadata(NULL, false);
5277
+ a->block_alloc = upb_Arena_MakeBlockAlloc(alloc, 0);
5278
+ upb_Atomic_Init(&a->parent_or_count, _upb_Arena_TaggedFromRefcount(1));
5279
+ upb_Atomic_Init(&a->next, NULL);
5280
+ upb_Atomic_Init(&a->tail, a);
5281
+ upb_Atomic_Init(&a->blocks, NULL);
5209
5282
 
5210
- upb_Arena_addblock(a, a, mem, n);
5283
+ upb_Arena_AddBlock(a, mem, n);
5211
5284
 
5212
5285
  return a;
5213
5286
  }
@@ -5228,343 +5301,189 @@ upb_Arena* upb_Arena_Init(void* mem, size_t n, upb_alloc* alloc) {
5228
5301
  n = UPB_ALIGN_DOWN(n, UPB_ALIGN_OF(upb_Arena));
5229
5302
 
5230
5303
  if (UPB_UNLIKELY(n < sizeof(upb_Arena))) {
5231
- return arena_initslow(mem, n, alloc);
5304
+ return upb_Arena_InitSlow(alloc);
5232
5305
  }
5233
5306
 
5234
5307
  a = UPB_PTR_AT(mem, n - sizeof(*a), upb_Arena);
5235
5308
 
5236
- a->block_alloc = alloc;
5237
- a->parent = a;
5238
- a->refcount = 1;
5239
- a->last_size = UPB_MAX(128, n);
5309
+ upb_Atomic_Init(&a->parent_or_count, _upb_Arena_TaggedFromRefcount(1));
5310
+ upb_Atomic_Init(&a->next, NULL);
5311
+ upb_Atomic_Init(&a->tail, a);
5312
+ upb_Atomic_Init(&a->blocks, NULL);
5313
+ a->block_alloc = upb_Arena_MakeBlockAlloc(alloc, 1);
5240
5314
  a->head.ptr = mem;
5241
5315
  a->head.end = UPB_PTR_AT(mem, n - sizeof(*a), char);
5242
- a->freelist = NULL;
5243
- a->freelist_tail = NULL;
5244
- a->cleanup_metadata = upb_cleanup_metadata(NULL, true);
5245
5316
 
5246
5317
  return a;
5247
5318
  }
5248
5319
 
5249
5320
  static void arena_dofree(upb_Arena* a) {
5250
- _upb_MemBlock* block = a->freelist;
5251
- UPB_ASSERT(a->parent == a);
5252
- UPB_ASSERT(a->refcount == 0);
5253
-
5254
- while (block) {
5255
- /* Load first since we are deleting block. */
5256
- _upb_MemBlock* next = block->next;
5257
-
5258
- if (block->cleanups > 0) {
5259
- cleanup_ent* end = UPB_PTR_AT(block, block->size, void);
5260
- cleanup_ent* ptr = end - block->cleanups;
5321
+ UPB_ASSERT(_upb_Arena_RefCountFromTagged(a->parent_or_count) == 1);
5261
5322
 
5262
- for (; ptr < end; ptr++) {
5263
- ptr->cleanup(ptr->ud);
5264
- }
5323
+ while (a != NULL) {
5324
+ // Load first since arena itself is likely from one of its blocks.
5325
+ upb_Arena* next_arena =
5326
+ (upb_Arena*)upb_Atomic_Load(&a->next, memory_order_acquire);
5327
+ upb_alloc* block_alloc = upb_Arena_BlockAlloc(a);
5328
+ _upb_MemBlock* block = upb_Atomic_Load(&a->blocks, memory_order_acquire);
5329
+ while (block != NULL) {
5330
+ // Load first since we are deleting block.
5331
+ _upb_MemBlock* next_block =
5332
+ upb_Atomic_Load(&block->next, memory_order_acquire);
5333
+ upb_free(block_alloc, block);
5334
+ block = next_block;
5265
5335
  }
5266
-
5267
- upb_free(a->block_alloc, block);
5268
- block = next;
5336
+ a = next_arena;
5269
5337
  }
5270
5338
  }
5271
5339
 
5272
5340
  void upb_Arena_Free(upb_Arena* a) {
5273
- a = arena_findroot(a);
5274
- if (--a->refcount == 0) arena_dofree(a);
5275
- }
5276
-
5277
- bool upb_Arena_AddCleanup(upb_Arena* a, void* ud, upb_CleanupFunc* func) {
5278
- cleanup_ent* ent;
5279
- uint32_t* cleanups = upb_cleanup_pointer(a->cleanup_metadata);
5341
+ uintptr_t poc = upb_Atomic_Load(&a->parent_or_count, memory_order_acquire);
5342
+ retry:
5343
+ while (_upb_Arena_IsTaggedPointer(poc)) {
5344
+ a = _upb_Arena_PointerFromTagged(poc);
5345
+ poc = upb_Atomic_Load(&a->parent_or_count, memory_order_acquire);
5346
+ }
5347
+
5348
+ // compare_exchange or fetch_sub are RMW operations, which are more
5349
+ // expensive then direct loads. As an optimization, we only do RMW ops
5350
+ // when we need to update things for other threads to see.
5351
+ if (poc == _upb_Arena_TaggedFromRefcount(1)) {
5352
+ arena_dofree(a);
5353
+ return;
5354
+ }
5280
5355
 
5281
- if (!cleanups || _upb_ArenaHas(a) < sizeof(cleanup_ent)) {
5282
- if (!upb_Arena_Allocblock(a, 128)) return false; /* Out of memory. */
5283
- UPB_ASSERT(_upb_ArenaHas(a) >= sizeof(cleanup_ent));
5284
- cleanups = upb_cleanup_pointer(a->cleanup_metadata);
5356
+ if (upb_Atomic_CompareExchangeWeak(
5357
+ &a->parent_or_count, &poc,
5358
+ _upb_Arena_TaggedFromRefcount(_upb_Arena_RefCountFromTagged(poc) - 1),
5359
+ memory_order_release, memory_order_acquire)) {
5360
+ // We were >1 and we decremented it successfully, so we are done.
5361
+ return;
5285
5362
  }
5286
5363
 
5287
- a->head.end -= sizeof(cleanup_ent);
5288
- ent = (cleanup_ent*)a->head.end;
5289
- (*cleanups)++;
5290
- UPB_UNPOISON_MEMORY_REGION(ent, sizeof(cleanup_ent));
5364
+ // We failed our update, so someone has done something, retry the whole
5365
+ // process, but the failed exchange reloaded `poc` for us.
5366
+ goto retry;
5367
+ }
5291
5368
 
5292
- ent->cleanup = func;
5293
- ent->ud = ud;
5369
+ static void _upb_Arena_DoFuseArenaLists(upb_Arena* const parent,
5370
+ upb_Arena* child) {
5371
+ upb_Arena* parent_tail = upb_Atomic_Load(&parent->tail, memory_order_relaxed);
5372
+ do {
5373
+ // Our tail might be stale, but it will always converge to the true tail.
5374
+ upb_Arena* parent_tail_next =
5375
+ upb_Atomic_Load(&parent_tail->next, memory_order_relaxed);
5376
+ while (parent_tail_next != NULL) {
5377
+ parent_tail = parent_tail_next;
5378
+ parent_tail_next =
5379
+ upb_Atomic_Load(&parent_tail->next, memory_order_relaxed);
5380
+ }
5294
5381
 
5295
- return true;
5296
- }
5382
+ upb_Arena* displaced =
5383
+ upb_Atomic_Exchange(&parent_tail->next, child, memory_order_relaxed);
5384
+ parent_tail = upb_Atomic_Load(&child->tail, memory_order_relaxed);
5297
5385
 
5298
- bool upb_Arena_Fuse(upb_Arena* a1, upb_Arena* a2) {
5299
- upb_Arena* r1 = arena_findroot(a1);
5300
- upb_Arena* r2 = arena_findroot(a2);
5386
+ // If we displaced something that got installed racily, we can simply
5387
+ // reinstall it on our new tail.
5388
+ child = displaced;
5389
+ } while (child != NULL);
5301
5390
 
5302
- if (r1 == r2) return true; /* Already fused. */
5391
+ upb_Atomic_Store(&parent->tail, parent_tail, memory_order_relaxed);
5392
+ }
5303
5393
 
5304
- /* Do not fuse initial blocks since we cannot lifetime extend them. */
5305
- if (upb_cleanup_has_initial_block(r1->cleanup_metadata)) return false;
5306
- if (upb_cleanup_has_initial_block(r2->cleanup_metadata)) return false;
5394
+ static upb_Arena* _upb_Arena_DoFuse(upb_Arena* a1, upb_Arena* a2,
5395
+ uintptr_t* ref_delta) {
5396
+ // `parent_or_count` has two disctint modes
5397
+ // - parent pointer mode
5398
+ // - refcount mode
5399
+ //
5400
+ // In parent pointer mode, it may change what pointer it refers to in the
5401
+ // tree, but it will always approach a root. Any operation that walks the
5402
+ // tree to the root may collapse levels of the tree concurrently.
5403
+ _upb_ArenaRoot r1 = _upb_Arena_FindRoot(a1);
5404
+ _upb_ArenaRoot r2 = _upb_Arena_FindRoot(a2);
5307
5405
 
5308
- /* Only allow fuse with a common allocator */
5309
- if (r1->block_alloc != r2->block_alloc) return false;
5406
+ if (r1.root == r2.root) return r1.root; // Already fused.
5310
5407
 
5311
- /* We want to join the smaller tree to the larger tree.
5312
- * So swap first if they are backwards. */
5313
- if (r1->refcount < r2->refcount) {
5314
- upb_Arena* tmp = r1;
5408
+ // Avoid cycles by always fusing into the root with the lower address.
5409
+ if ((uintptr_t)r1.root > (uintptr_t)r2.root) {
5410
+ _upb_ArenaRoot tmp = r1;
5315
5411
  r1 = r2;
5316
5412
  r2 = tmp;
5317
5413
  }
5318
5414
 
5319
- /* r1 takes over r2's freelist and refcount. */
5320
- r1->refcount += r2->refcount;
5321
- if (r2->freelist_tail) {
5322
- UPB_ASSERT(r2->freelist_tail->next == NULL);
5323
- r2->freelist_tail->next = r1->freelist;
5324
- r1->freelist = r2->freelist;
5325
- }
5326
- r2->parent = r1;
5327
- return true;
5328
- }
5329
-
5330
-
5331
-
5332
- // Must be last.
5333
-
5334
- // Parses unknown data by merging into existing base_message or creating a
5335
- // new message usingg mini_table.
5336
- static upb_UnknownToMessageRet upb_MiniTable_ParseUnknownMessage(
5337
- const char* unknown_data, size_t unknown_size,
5338
- const upb_MiniTable* mini_table, upb_Message* base_message,
5339
- int decode_options, upb_Arena* arena) {
5340
- upb_UnknownToMessageRet ret;
5341
- ret.message =
5342
- base_message ? base_message : _upb_Message_New(mini_table, arena);
5343
- if (!ret.message) {
5344
- ret.status = kUpb_UnknownToMessage_OutOfMemory;
5345
- return ret;
5346
- }
5347
- // Decode sub message using unknown field contents.
5348
- const char* data = unknown_data;
5349
- uint32_t tag;
5350
- uint64_t message_len = 0;
5351
- data = upb_WireReader_ReadTag(data, &tag);
5352
- data = upb_WireReader_ReadVarint(data, &message_len);
5353
- upb_DecodeStatus status = upb_Decode(data, message_len, ret.message,
5354
- mini_table, NULL, decode_options, arena);
5355
- if (status == kUpb_DecodeStatus_OutOfMemory) {
5356
- ret.status = kUpb_UnknownToMessage_OutOfMemory;
5357
- } else if (status == kUpb_DecodeStatus_Ok) {
5358
- ret.status = kUpb_UnknownToMessage_Ok;
5359
- } else {
5360
- ret.status = kUpb_UnknownToMessage_ParseError;
5415
+ // The moment we install `r1` as the parent for `r2` all racing frees may
5416
+ // immediately begin decrementing `r1`'s refcount (including pending
5417
+ // increments to that refcount and their frees!). We need to add `r2`'s refs
5418
+ // now, so that `r1` can withstand any unrefs that come from r2.
5419
+ //
5420
+ // Note that while it is possible for `r2`'s refcount to increase
5421
+ // asynchronously, we will not actually do the reparenting operation below
5422
+ // unless `r2`'s refcount is unchanged from when we read it.
5423
+ //
5424
+ // Note that we may have done this previously, either to this node or a
5425
+ // different node, during a previous and failed DoFuse() attempt. But we will
5426
+ // not lose track of these refs because we always add them to our overall
5427
+ // delta.
5428
+ uintptr_t r2_untagged_count = r2.tagged_count & ~1;
5429
+ uintptr_t with_r2_refs = r1.tagged_count + r2_untagged_count;
5430
+ if (!upb_Atomic_CompareExchangeStrong(
5431
+ &r1.root->parent_or_count, &r1.tagged_count, with_r2_refs,
5432
+ memory_order_release, memory_order_acquire)) {
5433
+ return NULL;
5361
5434
  }
5362
- return ret;
5363
- }
5364
5435
 
5365
- upb_GetExtension_Status upb_MiniTable_GetOrPromoteExtension(
5366
- upb_Message* msg, const upb_MiniTableExtension* ext_table,
5367
- int decode_options, upb_Arena* arena,
5368
- const upb_Message_Extension** extension) {
5369
- UPB_ASSERT(ext_table->field.descriptortype == kUpb_FieldType_Message);
5370
- *extension = _upb_Message_Getext(msg, ext_table);
5371
- if (*extension) {
5372
- return kUpb_GetExtension_Ok;
5436
+ // Perform the actual fuse by removing the refs from `r2` and swapping in the
5437
+ // parent pointer.
5438
+ if (!upb_Atomic_CompareExchangeStrong(
5439
+ &r2.root->parent_or_count, &r2.tagged_count,
5440
+ _upb_Arena_TaggedFromPointer(r1.root), memory_order_release,
5441
+ memory_order_acquire)) {
5442
+ // We'll need to remove the excess refs we added to r1 previously.
5443
+ *ref_delta += r2_untagged_count;
5444
+ return NULL;
5373
5445
  }
5374
5446
 
5375
- // Check unknown fields, if available promote.
5376
- int field_number = ext_table->field.number;
5377
- upb_FindUnknownRet result = upb_MiniTable_FindUnknown(msg, field_number);
5378
- if (result.status != kUpb_FindUnknown_Ok) {
5379
- return kUpb_GetExtension_NotPresent;
5380
- }
5381
- size_t len;
5382
- size_t ofs = result.ptr - upb_Message_GetUnknown(msg, &len);
5383
- // Decode and promote from unknown.
5384
- const upb_MiniTable* extension_table = ext_table->sub.submsg;
5385
- upb_UnknownToMessageRet parse_result = upb_MiniTable_ParseUnknownMessage(
5386
- result.ptr, result.len, extension_table,
5387
- /* base_message= */ NULL, decode_options, arena);
5388
- switch (parse_result.status) {
5389
- case kUpb_UnknownToMessage_OutOfMemory:
5390
- return kUpb_GetExtension_OutOfMemory;
5391
- case kUpb_UnknownToMessage_ParseError:
5392
- return kUpb_GetExtension_ParseError;
5393
- case kUpb_UnknownToMessage_NotFound:
5394
- return kUpb_GetExtension_NotPresent;
5395
- case kUpb_UnknownToMessage_Ok:
5396
- break;
5397
- }
5398
- upb_Message* extension_msg = parse_result.message;
5399
- // Add to extensions.
5400
- upb_Message_Extension* ext =
5401
- _upb_Message_GetOrCreateExtension(msg, ext_table, arena);
5402
- if (!ext) {
5403
- return kUpb_GetExtension_OutOfMemory;
5404
- }
5405
- memcpy(&ext->data, &extension_msg, sizeof(extension_msg));
5406
- *extension = ext;
5407
- const char* delete_ptr = upb_Message_GetUnknown(msg, &len) + ofs;
5408
- upb_Message_DeleteUnknown(msg, delete_ptr, result.len);
5409
- return kUpb_GetExtension_Ok;
5410
- }
5411
-
5412
- upb_GetExtensionAsBytes_Status upb_MiniTable_GetExtensionAsBytes(
5413
- const upb_Message* msg, const upb_MiniTableExtension* ext_table,
5414
- int encode_options, upb_Arena* arena, const char** extension_data,
5415
- size_t* len) {
5416
- const upb_Message_Extension* msg_ext = _upb_Message_Getext(msg, ext_table);
5417
- UPB_ASSERT(ext_table->field.descriptortype == kUpb_FieldType_Message);
5418
- if (msg_ext) {
5419
- upb_EncodeStatus status =
5420
- upb_Encode(msg_ext->data.ptr, msg_ext->ext->sub.submsg, encode_options,
5421
- arena, (char**)extension_data, len);
5422
- if (status != kUpb_EncodeStatus_Ok) {
5423
- return kUpb_GetExtensionAsBytes_EncodeError;
5424
- }
5425
- return kUpb_GetExtensionAsBytes_Ok;
5426
- }
5427
- int field_number = ext_table->field.number;
5428
- upb_FindUnknownRet result = upb_MiniTable_FindUnknown(msg, field_number);
5429
- if (result.status != kUpb_FindUnknown_Ok) {
5430
- return kUpb_GetExtensionAsBytes_NotPresent;
5431
- }
5432
- const char* data = result.ptr;
5433
- uint32_t tag;
5434
- uint64_t message_len = 0;
5435
- data = upb_WireReader_ReadTag(data, &tag);
5436
- data = upb_WireReader_ReadVarint(data, &message_len);
5437
- *extension_data = data;
5438
- *len = message_len;
5439
- return kUpb_GetExtensionAsBytes_Ok;
5447
+ // Now that the fuse has been performed (and can no longer fail) we need to
5448
+ // append `r2` to `r1`'s linked list.
5449
+ _upb_Arena_DoFuseArenaLists(r1.root, r2.root);
5450
+ return r1.root;
5440
5451
  }
5441
5452
 
5442
- static upb_FindUnknownRet upb_FindUnknownRet_ParseError(void) {
5443
- return (upb_FindUnknownRet){.status = kUpb_FindUnknown_ParseError};
5453
+ static bool _upb_Arena_FixupRefs(upb_Arena* new_root, uintptr_t ref_delta) {
5454
+ if (ref_delta == 0) return true; // No fixup required.
5455
+ uintptr_t poc =
5456
+ upb_Atomic_Load(&new_root->parent_or_count, memory_order_relaxed);
5457
+ if (_upb_Arena_IsTaggedPointer(poc)) return false;
5458
+ uintptr_t with_refs = poc - ref_delta;
5459
+ UPB_ASSERT(!_upb_Arena_IsTaggedPointer(with_refs));
5460
+ return upb_Atomic_CompareExchangeStrong(&new_root->parent_or_count, &poc,
5461
+ with_refs, memory_order_relaxed,
5462
+ memory_order_relaxed);
5444
5463
  }
5445
5464
 
5446
- upb_FindUnknownRet upb_MiniTable_FindUnknown(const upb_Message* msg,
5447
- uint32_t field_number) {
5448
- const int depth_limit = 100; // TODO: this should be a parameter
5449
- size_t size;
5450
- upb_FindUnknownRet ret;
5451
-
5452
- const char* ptr = upb_Message_GetUnknown(msg, &size);
5453
- upb_EpsCopyInputStream stream;
5454
- upb_EpsCopyInputStream_Init(&stream, &ptr, size, true);
5455
-
5456
- while (!upb_EpsCopyInputStream_IsDone(&stream, &ptr)) {
5457
- uint32_t tag;
5458
- const char* unknown_begin = ptr;
5459
- ptr = upb_WireReader_ReadTag(ptr, &tag);
5460
- if (!ptr) return upb_FindUnknownRet_ParseError();
5461
- if (field_number == upb_WireReader_GetFieldNumber(tag)) {
5462
- ret.status = kUpb_FindUnknown_Ok;
5463
- ret.ptr = upb_EpsCopyInputStream_GetAliasedPtr(&stream, unknown_begin);
5464
- ptr = _upb_WireReader_SkipValue(ptr, tag, depth_limit, &stream);
5465
- // Because we know that the input is a flat buffer, it is safe to perform
5466
- // pointer arithmetic on aliased pointers.
5467
- ret.len = upb_EpsCopyInputStream_GetAliasedPtr(&stream, ptr) - ret.ptr;
5468
- return ret;
5469
- }
5465
+ bool upb_Arena_Fuse(upb_Arena* a1, upb_Arena* a2) {
5466
+ if (a1 == a2) return true; // trivial fuse
5470
5467
 
5471
- ptr = _upb_WireReader_SkipValue(ptr, tag, depth_limit, &stream);
5472
- if (!ptr) return upb_FindUnknownRet_ParseError();
5468
+ // Do not fuse initial blocks since we cannot lifetime extend them.
5469
+ // Any other fuse scenario is allowed.
5470
+ if (upb_Arena_HasInitialBlock(a1) || upb_Arena_HasInitialBlock(a2)) {
5471
+ return false;
5473
5472
  }
5474
- ret.status = kUpb_FindUnknown_NotPresent;
5475
- ret.ptr = NULL;
5476
- ret.len = 0;
5477
- return ret;
5478
- }
5479
5473
 
5480
- // Warning: See TODO(b/267655898)
5481
- upb_UnknownToMessageRet upb_MiniTable_PromoteUnknownToMessage(
5482
- upb_Message* msg, const upb_MiniTable* mini_table,
5483
- const upb_MiniTableField* field, const upb_MiniTable* sub_mini_table,
5484
- int decode_options, upb_Arena* arena) {
5485
- upb_FindUnknownRet unknown;
5486
- // We need to loop and merge unknowns that have matching tag field->number.
5487
- upb_Message* message = NULL;
5488
- // Callers should check that message is not set first before calling
5489
- // PromotoUnknownToMessage.
5490
- UPB_ASSERT(mini_table->subs[field->submsg_index].submsg == sub_mini_table);
5491
- bool is_oneof = _upb_MiniTableField_InOneOf(field);
5492
- if (!is_oneof || _upb_getoneofcase_field(msg, field) == field->number) {
5493
- UPB_ASSERT(upb_Message_GetMessage(msg, field, NULL) == NULL);
5494
- }
5495
- upb_UnknownToMessageRet ret;
5496
- ret.status = kUpb_UnknownToMessage_Ok;
5497
- do {
5498
- unknown = upb_MiniTable_FindUnknown(msg, field->number);
5499
- switch (unknown.status) {
5500
- case kUpb_FindUnknown_Ok: {
5501
- const char* unknown_data = unknown.ptr;
5502
- size_t unknown_size = unknown.len;
5503
- ret = upb_MiniTable_ParseUnknownMessage(unknown_data, unknown_size,
5504
- sub_mini_table, message,
5505
- decode_options, arena);
5506
- if (ret.status == kUpb_UnknownToMessage_Ok) {
5507
- message = ret.message;
5508
- upb_Message_DeleteUnknown(msg, unknown_data, unknown_size);
5509
- }
5510
- } break;
5511
- case kUpb_FindUnknown_ParseError:
5512
- ret.status = kUpb_UnknownToMessage_ParseError;
5513
- break;
5514
- case kUpb_FindUnknown_NotPresent:
5515
- // If we parsed at least one unknown, we are done.
5516
- ret.status =
5517
- message ? kUpb_UnknownToMessage_Ok : kUpb_UnknownToMessage_NotFound;
5518
- break;
5519
- }
5520
- } while (unknown.status == kUpb_FindUnknown_Ok);
5521
- if (message) {
5522
- if (is_oneof) {
5523
- *_upb_oneofcase_field(msg, field) = field->number;
5474
+ // The number of refs we ultimately need to transfer to the new root.
5475
+ uintptr_t ref_delta = 0;
5476
+ while (true) {
5477
+ upb_Arena* new_root = _upb_Arena_DoFuse(a1, a2, &ref_delta);
5478
+ if (new_root != NULL && _upb_Arena_FixupRefs(new_root, ref_delta)) {
5479
+ return true;
5524
5480
  }
5525
- upb_Message_SetMessage(msg, mini_table, field, message);
5526
- ret.message = message;
5527
5481
  }
5528
- return ret;
5529
5482
  }
5530
5483
 
5531
- // Moves repeated messages in unknowns to a upb_Array.
5532
- //
5533
- // Since the repeated field is not a scalar type we don't check for
5534
- // kUpb_LabelFlags_IsPacked.
5535
- // TODO(b/251007554): Optimize. Instead of converting messages one at a time,
5536
- // scan all unknown data once and compact.
5537
- upb_UnknownToMessage_Status upb_MiniTable_PromoteUnknownToMessageArray(
5538
- upb_Message* msg, const upb_MiniTableField* field,
5539
- const upb_MiniTable* mini_table, int decode_options, upb_Arena* arena) {
5540
- upb_Array* repeated_messages = upb_Message_GetMutableArray(msg, field);
5541
- // Find all unknowns with given field number and parse.
5542
- upb_FindUnknownRet unknown;
5543
- do {
5544
- unknown = upb_MiniTable_FindUnknown(msg, field->number);
5545
- if (unknown.status == kUpb_FindUnknown_Ok) {
5546
- upb_UnknownToMessageRet ret = upb_MiniTable_ParseUnknownMessage(
5547
- unknown.ptr, unknown.len, mini_table,
5548
- /* base_message= */ NULL, decode_options, arena);
5549
- if (ret.status == kUpb_UnknownToMessage_Ok) {
5550
- upb_MessageValue value;
5551
- value.msg_val = ret.message;
5552
- // Allocate array on demand before append.
5553
- if (!repeated_messages) {
5554
- upb_Message_ResizeArray(msg, field, 0, arena);
5555
- repeated_messages = upb_Message_GetMutableArray(msg, field);
5556
- }
5557
- if (!upb_Array_Append(repeated_messages, value, arena)) {
5558
- return kUpb_UnknownToMessage_OutOfMemory;
5559
- }
5560
- upb_Message_DeleteUnknown(msg, unknown.ptr, unknown.len);
5561
- } else {
5562
- return ret.status;
5563
- }
5564
- }
5565
- } while (unknown.status == kUpb_FindUnknown_Ok);
5566
- return kUpb_UnknownToMessage_Ok;
5567
- }
5484
+
5485
+
5486
+ // Must be last.
5568
5487
 
5569
5488
  upb_MapInsertStatus upb_Message_InsertMapEntry(upb_Map* map,
5570
5489
  const upb_MiniTable* mini_table,
@@ -5572,7 +5491,7 @@ upb_MapInsertStatus upb_Message_InsertMapEntry(upb_Map* map,
5572
5491
  upb_Message* map_entry_message,
5573
5492
  upb_Arena* arena) {
5574
5493
  const upb_MiniTable* map_entry_mini_table =
5575
- mini_table->subs[field->submsg_index].submsg;
5494
+ mini_table->subs[field->UPB_PRIVATE(submsg_index)].submsg;
5576
5495
  UPB_ASSERT(map_entry_mini_table);
5577
5496
  UPB_ASSERT(map_entry_mini_table->field_count == 2);
5578
5497
  const upb_MiniTableField* map_entry_key_field =
@@ -5592,41 +5511,6 @@ upb_MapInsertStatus upb_Message_InsertMapEntry(upb_Map* map,
5592
5511
  return upb_Map_Insert(map, map_entry_key, map_entry_value, arena);
5593
5512
  }
5594
5513
 
5595
- // Moves repeated messages in unknowns to a upb_Map.
5596
- upb_UnknownToMessage_Status upb_MiniTable_PromoteUnknownToMap(
5597
- upb_Message* msg, const upb_MiniTable* mini_table,
5598
- const upb_MiniTableField* field, int decode_options, upb_Arena* arena) {
5599
- const upb_MiniTable* map_entry_mini_table =
5600
- mini_table->subs[field->submsg_index].submsg;
5601
- UPB_ASSERT(map_entry_mini_table);
5602
- UPB_ASSERT(map_entry_mini_table);
5603
- UPB_ASSERT(map_entry_mini_table->field_count == 2);
5604
- UPB_ASSERT(upb_FieldMode_Get(field) == kUpb_FieldMode_Map);
5605
- // Find all unknowns with given field number and parse.
5606
- upb_FindUnknownRet unknown;
5607
- while (1) {
5608
- unknown = upb_MiniTable_FindUnknown(msg, field->number);
5609
- if (unknown.status != kUpb_FindUnknown_Ok) break;
5610
- upb_UnknownToMessageRet ret = upb_MiniTable_ParseUnknownMessage(
5611
- unknown.ptr, unknown.len, map_entry_mini_table,
5612
- /* base_message= */ NULL, decode_options, arena);
5613
- if (ret.status != kUpb_UnknownToMessage_Ok) return ret.status;
5614
- // Allocate map on demand before append.
5615
- upb_Map* map = upb_Message_GetOrCreateMutableMap(msg, map_entry_mini_table,
5616
- field, arena);
5617
- upb_Message* map_entry_message = ret.message;
5618
- upb_MapInsertStatus insert_status = upb_Message_InsertMapEntry(
5619
- map, mini_table, field, map_entry_message, arena);
5620
- if (insert_status == kUpb_MapInsertStatus_OutOfMemory) {
5621
- return kUpb_UnknownToMessage_OutOfMemory;
5622
- }
5623
- UPB_ASSUME(insert_status == kUpb_MapInsertStatus_Inserted ||
5624
- insert_status == kUpb_MapInsertStatus_Replaced);
5625
- upb_Message_DeleteUnknown(msg, unknown.ptr, unknown.len);
5626
- }
5627
- return kUpb_UnknownToMessage_Ok;
5628
- }
5629
-
5630
5514
 
5631
5515
  #include <math.h>
5632
5516
 
@@ -5816,7 +5700,7 @@ const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
5816
5700
  int hi = t->field_count - 1;
5817
5701
  while (lo <= hi) {
5818
5702
  int mid = (lo + hi) / 2;
5819
- int num = t->fields[mid].number;
5703
+ uint32_t num = t->fields[mid].number;
5820
5704
  if (num < number) {
5821
5705
  lo = mid + 1;
5822
5706
  continue;
@@ -5832,15 +5716,15 @@ const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
5832
5716
 
5833
5717
  upb_FieldType upb_MiniTableField_Type(const upb_MiniTableField* field) {
5834
5718
  if (field->mode & kUpb_LabelFlags_IsAlternate) {
5835
- if (field->descriptortype == kUpb_FieldType_Int32) {
5719
+ if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Int32) {
5836
5720
  return kUpb_FieldType_Enum;
5837
- } else if (field->descriptortype == kUpb_FieldType_Bytes) {
5721
+ } else if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Bytes) {
5838
5722
  return kUpb_FieldType_String;
5839
5723
  } else {
5840
5724
  UPB_ASSERT(false);
5841
5725
  }
5842
5726
  }
5843
- return field->descriptortype;
5727
+ return field->UPB_PRIVATE(descriptortype);
5844
5728
  }
5845
5729
 
5846
5730
  static bool upb_MiniTable_Is_Oneof(const upb_MiniTableField* f) {
@@ -5979,14 +5863,14 @@ static const char* upb_MiniTable_DecodeBase92Varint(upb_MtDecoder* d,
5979
5863
 
5980
5864
  static bool upb_MiniTable_HasSub(upb_MiniTableField* field,
5981
5865
  uint64_t msg_modifiers) {
5982
- switch (field->descriptortype) {
5866
+ switch (field->UPB_PRIVATE(descriptortype)) {
5983
5867
  case kUpb_FieldType_Message:
5984
5868
  case kUpb_FieldType_Group:
5985
5869
  case kUpb_FieldType_Enum:
5986
5870
  return true;
5987
5871
  case kUpb_FieldType_String:
5988
5872
  if (!(msg_modifiers & kUpb_MessageModifier_ValidateUtf8)) {
5989
- field->descriptortype = kUpb_FieldType_Bytes;
5873
+ field->UPB_PRIVATE(descriptortype) = kUpb_FieldType_Bytes;
5990
5874
  field->mode |= kUpb_LabelFlags_IsAlternate;
5991
5875
  }
5992
5876
  return false;
@@ -5997,25 +5881,25 @@ static bool upb_MiniTable_HasSub(upb_MiniTableField* field,
5997
5881
 
5998
5882
  static bool upb_MtDecoder_FieldIsPackable(upb_MiniTableField* field) {
5999
5883
  return (field->mode & kUpb_FieldMode_Array) &&
6000
- _upb_FieldType_IsPackable(field->descriptortype);
5884
+ upb_FieldType_IsPackable(field->UPB_PRIVATE(descriptortype));
6001
5885
  }
6002
5886
 
6003
5887
  static void upb_MiniTable_SetTypeAndSub(upb_MiniTableField* field,
6004
5888
  upb_FieldType type, uint32_t* sub_count,
6005
5889
  uint64_t msg_modifiers,
6006
5890
  bool is_proto3_enum) {
6007
- field->descriptortype = type;
5891
+ field->UPB_PRIVATE(descriptortype) = type;
6008
5892
 
6009
5893
  if (is_proto3_enum) {
6010
- UPB_ASSERT(field->descriptortype == kUpb_FieldType_Enum);
6011
- field->descriptortype = kUpb_FieldType_Int32;
5894
+ UPB_ASSERT(field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum);
5895
+ field->UPB_PRIVATE(descriptortype) = kUpb_FieldType_Int32;
6012
5896
  field->mode |= kUpb_LabelFlags_IsAlternate;
6013
5897
  }
6014
5898
 
6015
5899
  if (upb_MiniTable_HasSub(field, msg_modifiers)) {
6016
- field->submsg_index = sub_count ? (*sub_count)++ : 0;
5900
+ field->UPB_PRIVATE(submsg_index) = sub_count ? (*sub_count)++ : 0;
6017
5901
  } else {
6018
- field->submsg_index = kUpb_NoSub;
5902
+ field->UPB_PRIVATE(submsg_index) = kUpb_NoSub;
6019
5903
  }
6020
5904
 
6021
5905
  if (upb_MtDecoder_FieldIsPackable(field) &&
@@ -6085,14 +5969,14 @@ static void upb_MiniTable_SetField(upb_MtDecoder* d, uint8_t ch,
6085
5969
  field->offset = kHasbitPresence;
6086
5970
  if (type == kUpb_EncodedType_Group || type == kUpb_EncodedType_Message) {
6087
5971
  field->mode |= pointer_rep << kUpb_FieldRep_Shift;
6088
- } else if (type >= sizeof(kUpb_EncodedToFieldRep)) {
5972
+ } else if ((unsigned long)type >= sizeof(kUpb_EncodedToFieldRep)) {
6089
5973
  upb_MtDecoder_ErrorFormat(d, "Invalid field type: %d", (int)type);
6090
5974
  UPB_UNREACHABLE();
6091
5975
  } else {
6092
5976
  field->mode |= kUpb_EncodedToFieldRep[type] << kUpb_FieldRep_Shift;
6093
5977
  }
6094
5978
  }
6095
- if (type >= sizeof(kUpb_EncodedToType)) {
5979
+ if ((unsigned long)type >= sizeof(kUpb_EncodedToType)) {
6096
5980
  upb_MtDecoder_ErrorFormat(d, "Invalid field type: %d", (int)type);
6097
5981
  UPB_UNREACHABLE();
6098
5982
  }
@@ -6508,7 +6392,7 @@ static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) {
6508
6392
 
6509
6393
  static void upb_MtDecoder_ValidateEntryField(upb_MtDecoder* d,
6510
6394
  const upb_MiniTableField* f,
6511
- int expected_num) {
6395
+ uint32_t expected_num) {
6512
6396
  const char* name = expected_num == 1 ? "key" : "val";
6513
6397
  if (f->number != expected_num) {
6514
6398
  upb_MtDecoder_ErrorFormat(d,
@@ -6532,7 +6416,7 @@ static void upb_MtDecoder_ValidateEntryField(upb_MtDecoder* d,
6532
6416
 
6533
6417
  if ((1 << upb_MiniTableField_Type(f)) & not_ok_types) {
6534
6418
  upb_MtDecoder_ErrorFormat(d, "map %s cannot have type %d", name,
6535
- (int)f->descriptortype);
6419
+ (int)f->UPB_PRIVATE(descriptortype));
6536
6420
  }
6537
6421
  }
6538
6422
 
@@ -6585,37 +6469,17 @@ static void upb_MtDecoder_ParseMessageSet(upb_MtDecoder* d, const char* data,
6585
6469
  ret->required_count = 0;
6586
6470
  }
6587
6471
 
6588
- upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len,
6589
- upb_MiniTablePlatform platform,
6590
- upb_Arena* arena, void** buf,
6591
- size_t* buf_size,
6592
- upb_Status* status) {
6593
- upb_MtDecoder decoder = {
6594
- .platform = platform,
6595
- .vec =
6596
- {
6597
- .data = *buf,
6598
- .capacity = *buf_size / sizeof(*decoder.vec.data),
6599
- .size = 0,
6600
- },
6601
- .arena = arena,
6602
- .status = status,
6603
- .table = upb_Arena_Malloc(arena, sizeof(*decoder.table)),
6604
- };
6605
-
6606
- if (UPB_SETJMP(decoder.err)) {
6607
- decoder.table = NULL;
6608
- goto done;
6609
- }
6472
+ static upb_MiniTable* upb_MtDecoder_DoBuildMiniTableWithBuf(
6473
+ upb_MtDecoder* decoder, const char* data, size_t len, void** buf,
6474
+ size_t* buf_size) {
6475
+ upb_MtDecoder_CheckOutOfMemory(decoder, decoder->table);
6610
6476
 
6611
- upb_MtDecoder_CheckOutOfMemory(&decoder, decoder.table);
6612
-
6613
- decoder.table->size = 0;
6614
- decoder.table->field_count = 0;
6615
- decoder.table->ext = kUpb_ExtMode_NonExtendable;
6616
- decoder.table->dense_below = 0;
6617
- decoder.table->table_mask = -1;
6618
- decoder.table->required_count = 0;
6477
+ decoder->table->size = 0;
6478
+ decoder->table->field_count = 0;
6479
+ decoder->table->ext = kUpb_ExtMode_NonExtendable;
6480
+ decoder->table->dense_below = 0;
6481
+ decoder->table->table_mask = -1;
6482
+ decoder->table->required_count = 0;
6619
6483
 
6620
6484
  // Strip off and verify the version tag.
6621
6485
  if (!len--) goto done;
@@ -6623,29 +6487,64 @@ upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len,
6623
6487
 
6624
6488
  switch (vers) {
6625
6489
  case kUpb_EncodedVersion_MapV1:
6626
- upb_MtDecoder_ParseMap(&decoder, data, len);
6490
+ upb_MtDecoder_ParseMap(decoder, data, len);
6627
6491
  break;
6628
6492
 
6629
6493
  case kUpb_EncodedVersion_MessageV1:
6630
- upb_MtDecoder_ParseMessage(&decoder, data, len);
6631
- upb_MtDecoder_AssignHasbits(decoder.table);
6632
- upb_MtDecoder_SortLayoutItems(&decoder);
6633
- upb_MtDecoder_AssignOffsets(&decoder);
6494
+ upb_MtDecoder_ParseMessage(decoder, data, len);
6495
+ upb_MtDecoder_AssignHasbits(decoder->table);
6496
+ upb_MtDecoder_SortLayoutItems(decoder);
6497
+ upb_MtDecoder_AssignOffsets(decoder);
6634
6498
  break;
6635
6499
 
6636
6500
  case kUpb_EncodedVersion_MessageSetV1:
6637
- upb_MtDecoder_ParseMessageSet(&decoder, data, len);
6501
+ upb_MtDecoder_ParseMessageSet(decoder, data, len);
6638
6502
  break;
6639
6503
 
6640
6504
  default:
6641
- upb_MtDecoder_ErrorFormat(&decoder, "Invalid message version: %c", vers);
6505
+ upb_MtDecoder_ErrorFormat(decoder, "Invalid message version: %c", vers);
6642
6506
  UPB_UNREACHABLE();
6643
6507
  }
6644
6508
 
6645
6509
  done:
6646
- *buf = decoder.vec.data;
6647
- *buf_size = decoder.vec.capacity * sizeof(*decoder.vec.data);
6648
- return decoder.table;
6510
+ *buf = decoder->vec.data;
6511
+ *buf_size = decoder->vec.capacity * sizeof(*decoder->vec.data);
6512
+ return decoder->table;
6513
+ }
6514
+
6515
+ static upb_MiniTable* upb_MtDecoder_BuildMiniTableWithBuf(
6516
+ upb_MtDecoder* const decoder, const char* const data, const size_t len,
6517
+ void** const buf, size_t* const buf_size) {
6518
+ if (UPB_SETJMP(decoder->err) != 0) {
6519
+ *buf = decoder->vec.data;
6520
+ *buf_size = decoder->vec.capacity * sizeof(*decoder->vec.data);
6521
+ return NULL;
6522
+ }
6523
+
6524
+ return upb_MtDecoder_DoBuildMiniTableWithBuf(decoder, data, len, buf,
6525
+ buf_size);
6526
+ }
6527
+
6528
+ upb_MiniTable* upb_MiniTable_BuildWithBuf(const char* data, size_t len,
6529
+ upb_MiniTablePlatform platform,
6530
+ upb_Arena* arena, void** buf,
6531
+ size_t* buf_size,
6532
+ upb_Status* status) {
6533
+ upb_MtDecoder decoder = {
6534
+ .platform = platform,
6535
+ .vec =
6536
+ {
6537
+ .data = *buf,
6538
+ .capacity = *buf_size / sizeof(*decoder.vec.data),
6539
+ .size = 0,
6540
+ },
6541
+ .arena = arena,
6542
+ .status = status,
6543
+ .table = upb_Arena_Malloc(arena, sizeof(*decoder.table)),
6544
+ };
6545
+
6546
+ return upb_MtDecoder_BuildMiniTableWithBuf(&decoder, data, len, buf,
6547
+ buf_size);
6649
6548
  }
6650
6549
 
6651
6550
  static size_t upb_MiniTableEnum_Size(size_t count) {
@@ -6684,85 +6583,83 @@ static void upb_MiniTableEnum_BuildValue(upb_MtDecoder* d, uint32_t val) {
6684
6583
  }
6685
6584
  }
6686
6585
 
6687
- upb_MiniTableEnum* upb_MiniTableEnum_Build(const char* data, size_t len,
6688
- upb_Arena* arena,
6689
- upb_Status* status) {
6690
- upb_MtDecoder decoder = {
6691
- .enum_table = upb_Arena_Malloc(arena, upb_MiniTableEnum_Size(2)),
6692
- .enum_value_count = 0,
6693
- .enum_data_count = 0,
6694
- .enum_data_capacity = 1,
6695
- .status = status,
6696
- .end = UPB_PTRADD(data, len),
6697
- .arena = arena,
6698
- };
6699
-
6700
- if (UPB_SETJMP(decoder.err)) return NULL;
6701
-
6586
+ static upb_MiniTableEnum* upb_MtDecoder_DoBuildMiniTableEnum(
6587
+ upb_MtDecoder* decoder, const char* data, size_t len) {
6702
6588
  // If the string is non-empty then it must begin with a version tag.
6703
6589
  if (len) {
6704
6590
  if (*data != kUpb_EncodedVersion_EnumV1) {
6705
- upb_MtDecoder_ErrorFormat(&decoder, "Invalid enum version: %c", *data);
6591
+ upb_MtDecoder_ErrorFormat(decoder, "Invalid enum version: %c", *data);
6706
6592
  UPB_UNREACHABLE();
6707
6593
  }
6708
6594
  data++;
6709
6595
  len--;
6710
6596
  }
6711
6597
 
6712
- upb_MtDecoder_CheckOutOfMemory(&decoder, decoder.enum_table);
6598
+ upb_MtDecoder_CheckOutOfMemory(decoder, decoder->enum_table);
6713
6599
 
6714
6600
  // Guarantee at least 64 bits of mask without checking mask size.
6715
- decoder.enum_table->mask_limit = 64;
6716
- decoder.enum_table = _upb_MiniTable_AddEnumDataMember(&decoder, 0);
6717
- decoder.enum_table = _upb_MiniTable_AddEnumDataMember(&decoder, 0);
6601
+ decoder->enum_table->mask_limit = 64;
6602
+ decoder->enum_table = _upb_MiniTable_AddEnumDataMember(decoder, 0);
6603
+ decoder->enum_table = _upb_MiniTable_AddEnumDataMember(decoder, 0);
6718
6604
 
6719
- decoder.enum_table->value_count = 0;
6605
+ decoder->enum_table->value_count = 0;
6720
6606
 
6721
6607
  const char* ptr = data;
6722
6608
  uint32_t base = 0;
6723
6609
 
6724
- while (ptr < decoder.end) {
6610
+ while (ptr < decoder->end) {
6725
6611
  char ch = *ptr++;
6726
6612
  if (ch <= kUpb_EncodedValue_MaxEnumMask) {
6727
6613
  uint32_t mask = _upb_FromBase92(ch);
6728
6614
  for (int i = 0; i < 5; i++, base++, mask >>= 1) {
6729
- if (mask & 1) upb_MiniTableEnum_BuildValue(&decoder, base);
6615
+ if (mask & 1) upb_MiniTableEnum_BuildValue(decoder, base);
6730
6616
  }
6731
6617
  } else if (kUpb_EncodedValue_MinSkip <= ch &&
6732
6618
  ch <= kUpb_EncodedValue_MaxSkip) {
6733
6619
  uint32_t skip;
6734
- ptr = upb_MiniTable_DecodeBase92Varint(&decoder, ptr, ch,
6620
+ ptr = upb_MiniTable_DecodeBase92Varint(decoder, ptr, ch,
6735
6621
  kUpb_EncodedValue_MinSkip,
6736
6622
  kUpb_EncodedValue_MaxSkip, &skip);
6737
6623
  base += skip;
6738
6624
  } else {
6739
- upb_MtDecoder_ErrorFormat(&decoder, "Unexpected character: %c", ch);
6625
+ upb_MtDecoder_ErrorFormat(decoder, "Unexpected character: %c", ch);
6740
6626
  return NULL;
6741
6627
  }
6742
6628
  }
6743
6629
 
6744
- return decoder.enum_table;
6630
+ return decoder->enum_table;
6745
6631
  }
6746
6632
 
6747
- const char* _upb_MiniTableExtension_Build(const char* data, size_t len,
6748
- upb_MiniTableExtension* ext,
6749
- const upb_MiniTable* extendee,
6750
- upb_MiniTableSub sub,
6751
- upb_MiniTablePlatform platform,
6752
- upb_Status* status) {
6633
+ static upb_MiniTableEnum* upb_MtDecoder_BuildMiniTableEnum(
6634
+ upb_MtDecoder* const decoder, const char* const data, size_t const len) {
6635
+ if (UPB_SETJMP(decoder->err) != 0) return NULL;
6636
+ return upb_MtDecoder_DoBuildMiniTableEnum(decoder, data, len);
6637
+ }
6638
+
6639
+ upb_MiniTableEnum* upb_MiniTableEnum_Build(const char* data, size_t len,
6640
+ upb_Arena* arena,
6641
+ upb_Status* status) {
6753
6642
  upb_MtDecoder decoder = {
6754
- .arena = NULL,
6643
+ .enum_table = upb_Arena_Malloc(arena, upb_MiniTableEnum_Size(2)),
6644
+ .enum_value_count = 0,
6645
+ .enum_data_count = 0,
6646
+ .enum_data_capacity = 1,
6755
6647
  .status = status,
6756
- .table = NULL,
6757
- .platform = platform,
6648
+ .end = UPB_PTRADD(data, len),
6649
+ .arena = arena,
6758
6650
  };
6759
6651
 
6760
- if (UPB_SETJMP(decoder.err)) return NULL;
6652
+ return upb_MtDecoder_BuildMiniTableEnum(&decoder, data, len);
6653
+ }
6761
6654
 
6655
+ static const char* upb_MtDecoder_DoBuildMiniTableExtension(
6656
+ upb_MtDecoder* decoder, const char* data, size_t len,
6657
+ upb_MiniTableExtension* ext, const upb_MiniTable* extendee,
6658
+ upb_MiniTableSub sub) {
6762
6659
  // If the string is non-empty then it must begin with a version tag.
6763
6660
  if (len) {
6764
6661
  if (*data != kUpb_EncodedVersion_ExtensionV1) {
6765
- upb_MtDecoder_ErrorFormat(&decoder, "Invalid ext version: %c", *data);
6662
+ upb_MtDecoder_ErrorFormat(decoder, "Invalid ext version: %c", *data);
6766
6663
  UPB_UNREACHABLE();
6767
6664
  }
6768
6665
  data++;
@@ -6771,7 +6668,7 @@ const char* _upb_MiniTableExtension_Build(const char* data, size_t len,
6771
6668
 
6772
6669
  uint16_t count = 0;
6773
6670
  const char* ret =
6774
- upb_MtDecoder_Parse(&decoder, data, len, ext, sizeof(*ext), &count, NULL);
6671
+ upb_MtDecoder_Parse(decoder, data, len, ext, sizeof(*ext), &count, NULL);
6775
6672
  if (!ret || count != 1) return NULL;
6776
6673
 
6777
6674
  upb_MiniTableField* f = &ext->field;
@@ -6794,6 +6691,47 @@ const char* _upb_MiniTableExtension_Build(const char* data, size_t len,
6794
6691
  return ret;
6795
6692
  }
6796
6693
 
6694
+ static const char* upb_MtDecoder_BuildMiniTableExtension(
6695
+ upb_MtDecoder* const decoder, const char* const data, const size_t len,
6696
+ upb_MiniTableExtension* const ext, const upb_MiniTable* const extendee,
6697
+ const upb_MiniTableSub sub) {
6698
+ if (UPB_SETJMP(decoder->err) != 0) return NULL;
6699
+ return upb_MtDecoder_DoBuildMiniTableExtension(decoder, data, len, ext,
6700
+ extendee, sub);
6701
+ }
6702
+
6703
+ const char* _upb_MiniTableExtension_Init(const char* data, size_t len,
6704
+ upb_MiniTableExtension* ext,
6705
+ const upb_MiniTable* extendee,
6706
+ upb_MiniTableSub sub,
6707
+ upb_MiniTablePlatform platform,
6708
+ upb_Status* status) {
6709
+ upb_MtDecoder decoder = {
6710
+ .arena = NULL,
6711
+ .status = status,
6712
+ .table = NULL,
6713
+ .platform = platform,
6714
+ };
6715
+
6716
+ return upb_MtDecoder_BuildMiniTableExtension(&decoder, data, len, ext,
6717
+ extendee, sub);
6718
+ }
6719
+
6720
+ upb_MiniTableExtension* _upb_MiniTableExtension_Build(
6721
+ const char* data, size_t len, const upb_MiniTable* extendee,
6722
+ upb_MiniTableSub sub, upb_MiniTablePlatform platform, upb_Arena* arena,
6723
+ upb_Status* status) {
6724
+ upb_MiniTableExtension* ext =
6725
+ upb_Arena_Malloc(arena, sizeof(upb_MiniTableExtension));
6726
+ if (UPB_UNLIKELY(!ext)) return NULL;
6727
+
6728
+ const char* ptr = _upb_MiniTableExtension_Init(data, len, ext, extendee, sub,
6729
+ platform, status);
6730
+ if (UPB_UNLIKELY(!ptr)) return NULL;
6731
+
6732
+ return ext;
6733
+ }
6734
+
6797
6735
  upb_MiniTable* _upb_MiniTable_Build(const char* data, size_t len,
6798
6736
  upb_MiniTablePlatform platform,
6799
6737
  upb_Arena* arena, upb_Status* status) {
@@ -6815,7 +6753,7 @@ bool upb_MiniTable_SetSubMessage(upb_MiniTable* table,
6815
6753
 
6816
6754
  const bool sub_is_map = sub->ext & kUpb_ExtMode_IsMapEntry;
6817
6755
 
6818
- switch (field->descriptortype) {
6756
+ switch (field->UPB_PRIVATE(descriptortype)) {
6819
6757
  case kUpb_FieldType_Message:
6820
6758
  if (sub_is_map) {
6821
6759
  const bool table_is_map = table->ext & kUpb_ExtMode_IsMapEntry;
@@ -6833,7 +6771,8 @@ bool upb_MiniTable_SetSubMessage(upb_MiniTable* table,
6833
6771
  return false;
6834
6772
  }
6835
6773
 
6836
- upb_MiniTableSub* table_sub = (void*)&table->subs[field->submsg_index];
6774
+ upb_MiniTableSub* table_sub =
6775
+ (void*)&table->subs[field->UPB_PRIVATE(submsg_index)];
6837
6776
  table_sub->submsg = sub;
6838
6777
  return true;
6839
6778
  }
@@ -6845,11 +6784,73 @@ bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field,
6845
6784
  (uintptr_t)(table->fields + table->field_count));
6846
6785
  UPB_ASSERT(sub);
6847
6786
 
6848
- upb_MiniTableSub* table_sub = (void*)&table->subs[field->submsg_index];
6787
+ upb_MiniTableSub* table_sub =
6788
+ (void*)&table->subs[field->UPB_PRIVATE(submsg_index)];
6849
6789
  table_sub->subenum = sub;
6850
6790
  return true;
6851
6791
  }
6852
6792
 
6793
+ uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt,
6794
+ const upb_MiniTableField** subs) {
6795
+ uint32_t msg_count = 0;
6796
+ uint32_t enum_count = 0;
6797
+
6798
+ for (int i = 0; i < mt->field_count; i++) {
6799
+ const upb_MiniTableField* f = &mt->fields[i];
6800
+ if (upb_MiniTableField_CType(f) == kUpb_CType_Message) {
6801
+ *subs = f;
6802
+ ++subs;
6803
+ msg_count++;
6804
+ }
6805
+ }
6806
+
6807
+ for (int i = 0; i < mt->field_count; i++) {
6808
+ const upb_MiniTableField* f = &mt->fields[i];
6809
+ if (upb_MiniTableField_CType(f) == kUpb_CType_Enum) {
6810
+ *subs = f;
6811
+ ++subs;
6812
+ enum_count++;
6813
+ }
6814
+ }
6815
+
6816
+ return (msg_count << 16) | enum_count;
6817
+ }
6818
+
6819
+ // The list of sub_tables and sub_enums must exactly match the number and order
6820
+ // of sub-message fields and sub-enum fields given by upb_MiniTable_GetSubList()
6821
+ // above.
6822
+ bool upb_MiniTable_Link(upb_MiniTable* mt, const upb_MiniTable** sub_tables,
6823
+ size_t sub_table_count,
6824
+ const upb_MiniTableEnum** sub_enums,
6825
+ size_t sub_enum_count) {
6826
+ uint32_t msg_count = 0;
6827
+ uint32_t enum_count = 0;
6828
+
6829
+ for (int i = 0; i < mt->field_count; i++) {
6830
+ upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i];
6831
+ if (upb_MiniTableField_CType(f) == kUpb_CType_Message) {
6832
+ const upb_MiniTable* sub = sub_tables[msg_count++];
6833
+ if (msg_count > sub_table_count) return false;
6834
+ if (sub != NULL) {
6835
+ if (!upb_MiniTable_SetSubMessage(mt, f, sub)) return false;
6836
+ }
6837
+ }
6838
+ }
6839
+
6840
+ for (int i = 0; i < mt->field_count; i++) {
6841
+ upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i];
6842
+ if (upb_MiniTableField_CType(f) == kUpb_CType_Enum) {
6843
+ const upb_MiniTableEnum* sub = sub_enums[enum_count++];
6844
+ if (enum_count > sub_enum_count) return false;
6845
+ if (sub != NULL) {
6846
+ if (!upb_MiniTable_SetSubEnum(mt, f, sub)) return false;
6847
+ }
6848
+ }
6849
+ }
6850
+
6851
+ return true;
6852
+ }
6853
+
6853
6854
  #include <inttypes.h>
6854
6855
 
6855
6856
 
@@ -7022,7 +7023,7 @@ char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr,
7022
7023
  // are bit flags).
7023
7024
  encoded_type += kUpb_EncodedType_RepeatedBase;
7024
7025
 
7025
- if (_upb_FieldType_IsPackable(type)) {
7026
+ if (upb_FieldType_IsPackable(type)) {
7026
7027
  bool field_is_packed = field_mod & kUpb_FieldModifier_IsPacked;
7027
7028
  bool default_is_packed = in->state.msg_state.msg_modifiers &
7028
7029
  kUpb_MessageModifier_DefaultIsPacked;
@@ -7142,23 +7143,22 @@ upb_ExtensionRegistry* upb_ExtensionRegistry_New(upb_Arena* arena) {
7142
7143
  return r;
7143
7144
  }
7144
7145
 
7146
+ UPB_API bool upb_ExtensionRegistry_Add(upb_ExtensionRegistry* r,
7147
+ const upb_MiniTableExtension* e) {
7148
+ char buf[EXTREG_KEY_SIZE];
7149
+ extreg_key(buf, e->extendee, e->field.number);
7150
+ if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, NULL)) return false;
7151
+ return upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE,
7152
+ upb_value_constptr(e), r->arena);
7153
+ }
7154
+
7145
7155
  bool upb_ExtensionRegistry_AddArray(upb_ExtensionRegistry* r,
7146
7156
  const upb_MiniTableExtension** e,
7147
7157
  size_t count) {
7148
- char buf[EXTREG_KEY_SIZE];
7149
7158
  const upb_MiniTableExtension** start = e;
7150
7159
  const upb_MiniTableExtension** end = UPB_PTRADD(e, count);
7151
7160
  for (; e < end; e++) {
7152
- const upb_MiniTableExtension* ext = *e;
7153
- extreg_key(buf, ext->extendee, ext->field.number);
7154
- upb_value v;
7155
- if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, &v)) {
7156
- goto failure;
7157
- }
7158
- if (!upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE,
7159
- upb_value_constptr(ext), r->arena)) {
7160
- goto failure;
7161
- }
7161
+ if (!upb_ExtensionRegistry_Add(r, *e)) goto failure;
7162
7162
  }
7163
7163
  return true;
7164
7164
 
@@ -7166,6 +7166,7 @@ failure:
7166
7166
  // Back out the entries previously added.
7167
7167
  for (end = e, e = start; e < end; e++) {
7168
7168
  const upb_MiniTableExtension* ext = *e;
7169
+ char buf[EXTREG_KEY_SIZE];
7169
7170
  extreg_key(buf, ext->extendee, ext->field.number);
7170
7171
  upb_strtable_remove2(&r->exts, buf, EXTREG_KEY_SIZE, NULL);
7171
7172
  }
@@ -9035,7 +9036,7 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix,
9035
9036
  }
9036
9037
  } else if (has_type_name) {
9037
9038
  f->type_ =
9038
- UPB_FIELD_TYPE_UNSPECIFIED; // We'll fill this in in resolve_fielddef()
9039
+ UPB_FIELD_TYPE_UNSPECIFIED; // We'll assign this in resolve_fielddef()
9039
9040
  }
9040
9041
 
9041
9042
  if (f->type_ < kUpb_FieldType_Double || f->type_ > kUpb_FieldType_SInt64) {
@@ -9080,8 +9081,7 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix,
9080
9081
  upb_OneofDef* oneof = (upb_OneofDef*)upb_MessageDef_Oneof(m, oneof_index);
9081
9082
  f->scope.oneof = oneof;
9082
9083
 
9083
- bool ok = _upb_OneofDef_Insert(oneof, f, name.data, name.size, ctx->arena);
9084
- if (!ok) _upb_DefBuilder_OomErr(ctx);
9084
+ _upb_OneofDef_Insert(ctx, oneof, f, name.data, name.size);
9085
9085
  }
9086
9086
 
9087
9087
  UPB_DEF_SET_OPTIONS(f->opts, FieldDescriptorProto, FieldOptions, field_proto);
@@ -9320,9 +9320,9 @@ void _upb_FieldDef_BuildMiniTableExtension(upb_DefBuilder* ctx,
9320
9320
  } else if (_upb_FieldDef_IsClosedEnum(f)) {
9321
9321
  sub.subenum = _upb_EnumDef_MiniTable(f->sub.enumdef);
9322
9322
  }
9323
- bool ok2 = upb_MiniTableExtension_Build(desc.data, desc.size, mut_ext,
9324
- upb_MessageDef_MiniTable(f->msgdef),
9325
- sub, ctx->status);
9323
+ bool ok2 = upb_MiniTableExtension_Init(desc.data, desc.size, mut_ext,
9324
+ upb_MessageDef_MiniTable(f->msgdef),
9325
+ sub, ctx->status);
9326
9326
  if (!ok2) _upb_DefBuilder_Errf(ctx, "Could not build extension mini table");
9327
9327
  }
9328
9328
 
@@ -10803,15 +10803,35 @@ const upb_FieldDef* upb_OneofDef_LookupNumber(const upb_OneofDef* o,
10803
10803
  : NULL;
10804
10804
  }
10805
10805
 
10806
- bool _upb_OneofDef_Insert(upb_OneofDef* o, const upb_FieldDef* f,
10807
- const char* name, size_t size, upb_Arena* a) {
10806
+ void _upb_OneofDef_Insert(upb_DefBuilder* ctx, upb_OneofDef* o,
10807
+ const upb_FieldDef* f, const char* name,
10808
+ size_t size) {
10808
10809
  o->field_count++;
10809
10810
  if (_upb_FieldDef_IsProto3Optional(f)) o->synthetic = true;
10810
10811
 
10811
10812
  const int number = upb_FieldDef_Number(f);
10812
10813
  const upb_value v = upb_value_constptr(f);
10813
- return upb_inttable_insert(&o->itof, number, v, a) &&
10814
- upb_strtable_insert(&o->ntof, name, size, v, a);
10814
+
10815
+ // TODO(salo): This lookup is unfortunate because we also perform it when
10816
+ // inserting into the message's table. Unfortunately that step occurs after
10817
+ // this one and moving things around could be tricky so let's leave it for
10818
+ // a future refactoring.
10819
+ const bool number_exists = upb_inttable_lookup(&o->itof, number, NULL);
10820
+ if (UPB_UNLIKELY(number_exists)) {
10821
+ _upb_DefBuilder_Errf(ctx, "oneof fields have the same number (%d)", number);
10822
+ }
10823
+
10824
+ // TODO(salo): More redundant work happening here.
10825
+ const bool name_exists = upb_strtable_lookup2(&o->ntof, name, size, NULL);
10826
+ if (UPB_UNLIKELY(name_exists)) {
10827
+ _upb_DefBuilder_Errf(ctx, "oneof fields have the same name (%s)", name);
10828
+ }
10829
+
10830
+ const bool ok = upb_inttable_insert(&o->itof, number, v, ctx->arena) &&
10831
+ upb_strtable_insert(&o->ntof, name, size, v, ctx->arena);
10832
+ if (UPB_UNLIKELY(!ok)) {
10833
+ _upb_DefBuilder_OomErr(ctx);
10834
+ }
10815
10835
  }
10816
10836
 
10817
10837
  // Returns the synthetic count.
@@ -11168,7 +11188,7 @@ static void _upb_Decoder_Munge(int type, wireval* val) {
11168
11188
  static upb_Message* _upb_Decoder_NewSubMessage(
11169
11189
  upb_Decoder* d, const upb_MiniTableSub* subs,
11170
11190
  const upb_MiniTableField* field) {
11171
- const upb_MiniTable* subl = subs[field->submsg_index].submsg;
11191
+ const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg;
11172
11192
  UPB_ASSERT(subl);
11173
11193
  upb_Message* msg = _upb_Message_New(subl, &d->arena);
11174
11194
  if (!msg) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
@@ -11207,7 +11227,7 @@ static const char* _upb_Decoder_DecodeSubMessage(
11207
11227
  upb_Decoder* d, const char* ptr, upb_Message* submsg,
11208
11228
  const upb_MiniTableSub* subs, const upb_MiniTableField* field, int size) {
11209
11229
  int saved_delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, size);
11210
- const upb_MiniTable* subl = subs[field->submsg_index].submsg;
11230
+ const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg;
11211
11231
  UPB_ASSERT(subl);
11212
11232
  ptr = _upb_Decoder_RecurseSubMessage(d, ptr, submsg, subl, DECODE_NOGROUP);
11213
11233
  upb_EpsCopyInputStream_PopLimit(&d->input, ptr, saved_delta);
@@ -11238,7 +11258,7 @@ UPB_FORCEINLINE
11238
11258
  static const char* _upb_Decoder_DecodeKnownGroup(
11239
11259
  upb_Decoder* d, const char* ptr, upb_Message* submsg,
11240
11260
  const upb_MiniTableSub* subs, const upb_MiniTableField* field) {
11241
- const upb_MiniTable* subl = subs[field->submsg_index].submsg;
11261
+ const upb_MiniTable* subl = subs[field->UPB_PRIVATE(submsg_index)].submsg;
11242
11262
  UPB_ASSERT(subl);
11243
11263
  return _upb_Decoder_DecodeGroup(d, ptr, submsg, subl, field->number);
11244
11264
  }
@@ -11302,7 +11322,7 @@ static const char* _upb_Decoder_DecodeEnumArray(upb_Decoder* d, const char* ptr,
11302
11322
  const upb_MiniTableSub* subs,
11303
11323
  const upb_MiniTableField* field,
11304
11324
  wireval* val) {
11305
- const upb_MiniTableEnum* e = subs[field->submsg_index].subenum;
11325
+ const upb_MiniTableEnum* e = subs[field->UPB_PRIVATE(submsg_index)].subenum;
11306
11326
  if (!_upb_Decoder_CheckEnum(d, ptr, msg, e, field, val)) return ptr;
11307
11327
  void* mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->size * 4, void);
11308
11328
  arr->size++;
@@ -11356,7 +11376,7 @@ static const char* _upb_Decoder_DecodeVarintPacked(
11356
11376
  while (!_upb_Decoder_IsDone(d, &ptr)) {
11357
11377
  wireval elem;
11358
11378
  ptr = _upb_Decoder_DecodeVarint(d, ptr, &elem.uint64_val);
11359
- _upb_Decoder_Munge(field->descriptortype, &elem);
11379
+ _upb_Decoder_Munge(field->UPB_PRIVATE(descriptortype), &elem);
11360
11380
  if (_upb_Decoder_Reserve(d, arr, 1)) {
11361
11381
  out = UPB_PTR_AT(_upb_array_ptr(arr), arr->size << lg2, void);
11362
11382
  }
@@ -11373,7 +11393,7 @@ static const char* _upb_Decoder_DecodeEnumPacked(
11373
11393
  upb_Decoder* d, const char* ptr, upb_Message* msg, upb_Array* arr,
11374
11394
  const upb_MiniTableSub* subs, const upb_MiniTableField* field,
11375
11395
  wireval* val) {
11376
- const upb_MiniTableEnum* e = subs[field->submsg_index].subenum;
11396
+ const upb_MiniTableEnum* e = subs[field->UPB_PRIVATE(submsg_index)].subenum;
11377
11397
  int saved_limit = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, val->size);
11378
11398
  char* out = UPB_PTR_AT(_upb_array_ptr(arr), arr->size * 4, void);
11379
11399
  while (!_upb_Decoder_IsDone(d, &ptr)) {
@@ -11419,7 +11439,7 @@ upb_Array* _upb_Decoder_CreateArray(upb_Decoder* d,
11419
11439
  [kUpb_FieldType_SInt64] = 3,
11420
11440
  };
11421
11441
 
11422
- size_t lg2 = kElemSizeLg2[field->descriptortype];
11442
+ size_t lg2 = kElemSizeLg2[field->UPB_PRIVATE(descriptortype)];
11423
11443
  upb_Array* ret = _upb_Array_New(&d->arena, 4, lg2);
11424
11444
  if (!ret) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
11425
11445
  return ret;
@@ -11465,7 +11485,8 @@ static const char* _upb_Decoder_DecodeToArray(upb_Decoder* d, const char* ptr,
11465
11485
  *UPB_PTR_AT(_upb_array_ptr(arr), arr->size * sizeof(void*),
11466
11486
  upb_Message*) = submsg;
11467
11487
  arr->size++;
11468
- if (UPB_UNLIKELY(field->descriptortype == kUpb_FieldType_Group)) {
11488
+ if (UPB_UNLIKELY(field->UPB_PRIVATE(descriptortype) ==
11489
+ kUpb_FieldType_Group)) {
11469
11490
  return _upb_Decoder_DecodeKnownGroup(d, ptr, submsg, subs, field);
11470
11491
  } else {
11471
11492
  return _upb_Decoder_DecodeSubMessage(d, ptr, submsg, subs, field,
@@ -11516,8 +11537,8 @@ upb_Map* _upb_Decoder_CreateMap(upb_Decoder* d, const upb_MiniTable* entry) {
11516
11537
 
11517
11538
  const upb_MiniTableField* key_field = &entry->fields[0];
11518
11539
  const upb_MiniTableField* val_field = &entry->fields[1];
11519
- char key_size = kSizeInMap[key_field->descriptortype];
11520
- char val_size = kSizeInMap[val_field->descriptortype];
11540
+ char key_size = kSizeInMap[key_field->UPB_PRIVATE(descriptortype)];
11541
+ char val_size = kSizeInMap[val_field->UPB_PRIVATE(descriptortype)];
11521
11542
  UPB_ASSERT(key_field->offset == offsetof(upb_MapEntryData, k));
11522
11543
  UPB_ASSERT(val_field->offset == offsetof(upb_MapEntryData, v));
11523
11544
  upb_Map* ret = _upb_Map_New(&d->arena, key_size, val_size);
@@ -11534,7 +11555,7 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr,
11534
11555
  upb_Map* map = *map_p;
11535
11556
  upb_MapEntry ent;
11536
11557
  UPB_ASSERT(upb_MiniTableField_Type(field) == kUpb_FieldType_Message);
11537
- const upb_MiniTable* entry = subs[field->submsg_index].submsg;
11558
+ const upb_MiniTable* entry = subs[field->UPB_PRIVATE(submsg_index)].submsg;
11538
11559
 
11539
11560
  UPB_ASSERT(entry->field_count == 2);
11540
11561
  UPB_ASSERT(!upb_IsRepeatedOrMap(&entry->fields[0]));
@@ -11548,8 +11569,8 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr,
11548
11569
  // Parse map entry.
11549
11570
  memset(&ent, 0, sizeof(ent));
11550
11571
 
11551
- if (entry->fields[1].descriptortype == kUpb_FieldType_Message ||
11552
- entry->fields[1].descriptortype == kUpb_FieldType_Group) {
11572
+ if (entry->fields[1].UPB_PRIVATE(descriptortype) == kUpb_FieldType_Message ||
11573
+ entry->fields[1].UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group) {
11553
11574
  const upb_MiniTable* submsg_table = entry->subs[0].submsg;
11554
11575
  // Any sub-message entry must be linked. We do not allow dynamic tree
11555
11576
  // shaking in this case.
@@ -11592,10 +11613,11 @@ static const char* _upb_Decoder_DecodeToSubMessage(
11592
11613
  const upb_MiniTableSub* subs, const upb_MiniTableField* field, wireval* val,
11593
11614
  int op) {
11594
11615
  void* mem = UPB_PTR_AT(msg, field->offset, void);
11595
- int type = field->descriptortype;
11616
+ int type = field->UPB_PRIVATE(descriptortype);
11596
11617
 
11597
11618
  if (UPB_UNLIKELY(op == kUpb_DecodeOp_Enum) &&
11598
- !_upb_Decoder_CheckEnum(d, ptr, msg, subs[field->submsg_index].subenum,
11619
+ !_upb_Decoder_CheckEnum(d, ptr, msg,
11620
+ subs[field->UPB_PRIVATE(submsg_index)].subenum,
11599
11621
  field, val)) {
11600
11622
  return ptr;
11601
11623
  }
@@ -11838,7 +11860,7 @@ static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d,
11838
11860
  if (t->dense_below < t->field_count) {
11839
11861
  /* Linear search non-dense fields. Resume scanning from last_field_index
11840
11862
  * since fields are usually in order. */
11841
- int last = *last_field_index;
11863
+ size_t last = *last_field_index;
11842
11864
  for (idx = last; idx < t->field_count; idx++) {
11843
11865
  if (t->fields[idx].number == field_number) {
11844
11866
  goto found;
@@ -11902,7 +11924,7 @@ int _upb_Decoder_GetVarintOp(const upb_MiniTableField* field) {
11902
11924
  [kUpb_FakeFieldType_MessageSetItem] = kUpb_DecodeOp_UnknownField,
11903
11925
  };
11904
11926
 
11905
- return kVarintOps[field->descriptortype];
11927
+ return kVarintOps[field->UPB_PRIVATE(descriptortype)];
11906
11928
  }
11907
11929
 
11908
11930
  UPB_FORCEINLINE
@@ -11911,8 +11933,22 @@ static void _upb_Decoder_CheckUnlinked(const upb_MiniTable* mt,
11911
11933
  int* op) {
11912
11934
  // If sub-message is not linked, treat as unknown.
11913
11935
  if (field->mode & kUpb_LabelFlags_IsExtension) return;
11914
- const upb_MiniTableSub* sub = &mt->subs[field->submsg_index];
11915
- if (!sub->submsg) *op = kUpb_DecodeOp_UnknownField;
11936
+ const upb_MiniTableSub* sub = &mt->subs[field->UPB_PRIVATE(submsg_index)];
11937
+ if (sub->submsg) return;
11938
+ #ifndef NDEBUG
11939
+ const upb_MiniTableField* oneof = upb_MiniTable_GetOneof(mt, field);
11940
+ if (oneof) {
11941
+ // All other members of the oneof must be message fields that are also
11942
+ // unlinked.
11943
+ do {
11944
+ assert(upb_MiniTableField_CType(oneof) == kUpb_CType_Message);
11945
+ const upb_MiniTableSub* oneof_sub =
11946
+ &mt->subs[oneof->UPB_PRIVATE(submsg_index)];
11947
+ assert(!oneof_sub);
11948
+ } while (upb_MiniTable_NextOneofField(mt, &oneof));
11949
+ }
11950
+ #endif // NDEBUG
11951
+ *op = kUpb_DecodeOp_UnknownField;
11916
11952
  }
11917
11953
 
11918
11954
  int _upb_Decoder_GetDelimitedOp(const upb_MiniTable* mt,
@@ -11965,7 +12001,7 @@ int _upb_Decoder_GetDelimitedOp(const upb_MiniTable* mt,
11965
12001
  // repeated msgset type
11966
12002
  };
11967
12003
 
11968
- int ndx = field->descriptortype;
12004
+ int ndx = field->UPB_PRIVATE(descriptortype);
11969
12005
  if (upb_FieldMode_Get(field) == kUpb_FieldMode_Array) ndx += kRepeatedBase;
11970
12006
  int op = kDelimitedOps[ndx];
11971
12007
 
@@ -11994,17 +12030,17 @@ static const char* _upb_Decoder_DecodeWireValue(upb_Decoder* d, const char* ptr,
11994
12030
  case kUpb_WireType_Varint:
11995
12031
  ptr = _upb_Decoder_DecodeVarint(d, ptr, &val->uint64_val);
11996
12032
  *op = _upb_Decoder_GetVarintOp(field);
11997
- _upb_Decoder_Munge(field->descriptortype, val);
12033
+ _upb_Decoder_Munge(field->UPB_PRIVATE(descriptortype), val);
11998
12034
  return ptr;
11999
12035
  case kUpb_WireType_32Bit:
12000
12036
  *op = kUpb_DecodeOp_Scalar4Byte;
12001
- if (((1 << field->descriptortype) & kFixed32OkMask) == 0) {
12037
+ if (((1 << field->UPB_PRIVATE(descriptortype)) & kFixed32OkMask) == 0) {
12002
12038
  *op = kUpb_DecodeOp_UnknownField;
12003
12039
  }
12004
12040
  return upb_WireReader_ReadFixed32(ptr, &val->uint32_val);
12005
12041
  case kUpb_WireType_64Bit:
12006
12042
  *op = kUpb_DecodeOp_Scalar8Byte;
12007
- if (((1 << field->descriptortype) & kFixed64OkMask) == 0) {
12043
+ if (((1 << field->UPB_PRIVATE(descriptortype)) & kFixed64OkMask) == 0) {
12008
12044
  *op = kUpb_DecodeOp_UnknownField;
12009
12045
  }
12010
12046
  return upb_WireReader_ReadFixed64(ptr, &val->uint64_val);
@@ -12014,10 +12050,11 @@ static const char* _upb_Decoder_DecodeWireValue(upb_Decoder* d, const char* ptr,
12014
12050
  return ptr;
12015
12051
  case kUpb_WireType_StartGroup:
12016
12052
  val->uint32_val = field->number;
12017
- if (field->descriptortype == kUpb_FieldType_Group) {
12053
+ if (field->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group) {
12018
12054
  *op = kUpb_DecodeOp_SubMessage;
12019
12055
  _upb_Decoder_CheckUnlinked(mt, field, op);
12020
- } else if (field->descriptortype == kUpb_FakeFieldType_MessageSetItem) {
12056
+ } else if (field->UPB_PRIVATE(descriptortype) ==
12057
+ kUpb_FakeFieldType_MessageSetItem) {
12021
12058
  *op = kUpb_DecodeOp_MessageSetItem;
12022
12059
  } else {
12023
12060
  *op = kUpb_DecodeOp_UnknownField;
@@ -12231,9 +12268,10 @@ static upb_DecodeStatus upb_Decoder_Decode(upb_Decoder* const decoder,
12231
12268
  UPB_ASSERT(decoder->status != kUpb_DecodeStatus_Ok);
12232
12269
  }
12233
12270
 
12234
- arena->head.ptr = decoder->arena.head.ptr;
12235
- arena->head.end = decoder->arena.head.end;
12236
- arena->cleanup_metadata = decoder->arena.cleanup_metadata;
12271
+ _upb_MemBlock* blocks =
12272
+ upb_Atomic_Load(&decoder->arena.blocks, memory_order_relaxed);
12273
+ arena->head = decoder->arena.head;
12274
+ upb_Atomic_Store(&arena->blocks, blocks, memory_order_relaxed);
12237
12275
  return decoder->status;
12238
12276
  }
12239
12277
 
@@ -12241,25 +12279,31 @@ upb_DecodeStatus upb_Decode(const char* buf, size_t size, void* msg,
12241
12279
  const upb_MiniTable* l,
12242
12280
  const upb_ExtensionRegistry* extreg, int options,
12243
12281
  upb_Arena* arena) {
12244
- upb_Decoder state;
12282
+ upb_Decoder decoder;
12245
12283
  unsigned depth = (unsigned)options >> 16;
12246
12284
 
12247
- upb_EpsCopyInputStream_Init(&state.input, &buf, size,
12285
+ upb_EpsCopyInputStream_Init(&decoder.input, &buf, size,
12248
12286
  options & kUpb_DecodeOption_AliasString);
12249
12287
 
12250
- state.extreg = extreg;
12251
- state.unknown = NULL;
12252
- state.depth = depth ? depth : 64;
12253
- state.end_group = DECODE_NOGROUP;
12254
- state.options = (uint16_t)options;
12255
- state.missing_required = false;
12256
- state.arena.head = arena->head;
12257
- state.arena.last_size = arena->last_size;
12258
- state.arena.cleanup_metadata = arena->cleanup_metadata;
12259
- state.arena.parent = arena;
12260
- state.status = kUpb_DecodeStatus_Ok;
12288
+ decoder.extreg = extreg;
12289
+ decoder.unknown = NULL;
12290
+ decoder.depth = depth ? depth : kUpb_WireFormat_DefaultDepthLimit;
12291
+ decoder.end_group = DECODE_NOGROUP;
12292
+ decoder.options = (uint16_t)options;
12293
+ decoder.missing_required = false;
12294
+ decoder.status = kUpb_DecodeStatus_Ok;
12295
+
12296
+ // Violating the encapsulation of the arena for performance reasons.
12297
+ // This is a temporary arena that we swap into and swap out of when we are
12298
+ // done. The temporary arena only needs to be able to handle allocation,
12299
+ // not fuse or free, so it does not need many of the members to be initialized
12300
+ // (particularly parent_or_count).
12301
+ _upb_MemBlock* blocks = upb_Atomic_Load(&arena->blocks, memory_order_relaxed);
12302
+ decoder.arena.head = arena->head;
12303
+ decoder.arena.block_alloc = arena->block_alloc;
12304
+ upb_Atomic_Init(&decoder.arena.blocks, blocks);
12261
12305
 
12262
- return upb_Decoder_Decode(&state, buf, msg, l, arena);
12306
+ return upb_Decoder_Decode(&decoder, buf, msg, l, arena);
12263
12307
  }
12264
12308
 
12265
12309
  #undef OP_FIXPCK_LG2
@@ -13441,7 +13485,7 @@ static void encode_scalar(upb_encstate* e, const void* _field_mem,
13441
13485
  break; \
13442
13486
  }
13443
13487
 
13444
- switch (f->descriptortype) {
13488
+ switch (f->UPB_PRIVATE(descriptortype)) {
13445
13489
  case kUpb_FieldType_Double:
13446
13490
  CASE(double, double, kUpb_WireType_64Bit, val);
13447
13491
  case kUpb_FieldType_Float:
@@ -13477,7 +13521,7 @@ static void encode_scalar(upb_encstate* e, const void* _field_mem,
13477
13521
  case kUpb_FieldType_Group: {
13478
13522
  size_t size;
13479
13523
  void* submsg = *(void**)field_mem;
13480
- const upb_MiniTable* subm = subs[f->submsg_index].submsg;
13524
+ const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg;
13481
13525
  if (submsg == NULL) {
13482
13526
  return;
13483
13527
  }
@@ -13491,7 +13535,7 @@ static void encode_scalar(upb_encstate* e, const void* _field_mem,
13491
13535
  case kUpb_FieldType_Message: {
13492
13536
  size_t size;
13493
13537
  void* submsg = *(void**)field_mem;
13494
- const upb_MiniTable* subm = subs[f->submsg_index].submsg;
13538
+ const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg;
13495
13539
  if (submsg == NULL) {
13496
13540
  return;
13497
13541
  }
@@ -13536,7 +13580,7 @@ static void encode_array(upb_encstate* e, const upb_Message* msg,
13536
13580
 
13537
13581
  #define TAG(wire_type) (packed ? 0 : (f->number << 3 | wire_type))
13538
13582
 
13539
- switch (f->descriptortype) {
13583
+ switch (f->UPB_PRIVATE(descriptortype)) {
13540
13584
  case kUpb_FieldType_Double:
13541
13585
  encode_fixedarray(e, arr, sizeof(double), TAG(kUpb_WireType_64Bit));
13542
13586
  break;
@@ -13580,7 +13624,7 @@ static void encode_array(upb_encstate* e, const upb_Message* msg,
13580
13624
  case kUpb_FieldType_Group: {
13581
13625
  const void* const* start = _upb_array_constptr(arr);
13582
13626
  const void* const* ptr = start + arr->size;
13583
- const upb_MiniTable* subm = subs[f->submsg_index].submsg;
13627
+ const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg;
13584
13628
  if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded);
13585
13629
  do {
13586
13630
  size_t size;
@@ -13595,7 +13639,7 @@ static void encode_array(upb_encstate* e, const upb_Message* msg,
13595
13639
  case kUpb_FieldType_Message: {
13596
13640
  const void* const* start = _upb_array_constptr(arr);
13597
13641
  const void* const* ptr = start + arr->size;
13598
- const upb_MiniTable* subm = subs[f->submsg_index].submsg;
13642
+ const upb_MiniTable* subm = subs[f->UPB_PRIVATE(submsg_index)].submsg;
13599
13643
  if (--e->depth == 0) encode_err(e, kUpb_EncodeStatus_MaxDepthExceeded);
13600
13644
  do {
13601
13645
  size_t size;
@@ -13634,14 +13678,15 @@ static void encode_map(upb_encstate* e, const upb_Message* msg,
13634
13678
  const upb_MiniTableSub* subs,
13635
13679
  const upb_MiniTableField* f) {
13636
13680
  const upb_Map* map = *UPB_PTR_AT(msg, f->offset, const upb_Map*);
13637
- const upb_MiniTable* layout = subs[f->submsg_index].submsg;
13681
+ const upb_MiniTable* layout = subs[f->UPB_PRIVATE(submsg_index)].submsg;
13638
13682
  UPB_ASSERT(layout->field_count == 2);
13639
13683
 
13640
13684
  if (map == NULL) return;
13641
13685
 
13642
13686
  if (e->options & kUpb_EncodeOption_Deterministic) {
13643
13687
  _upb_sortedmap sorted;
13644
- _upb_mapsorter_pushmap(&e->sorter, layout->fields[0].descriptortype, map,
13688
+ _upb_mapsorter_pushmap(&e->sorter,
13689
+ layout->fields[0].UPB_PRIVATE(descriptortype), map,
13645
13690
  &sorted);
13646
13691
  upb_MapEntry ent;
13647
13692
  while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) {
@@ -13837,7 +13882,7 @@ upb_EncodeStatus upb_Encode(const void* msg, const upb_MiniTable* l,
13837
13882
  e.buf = NULL;
13838
13883
  e.limit = NULL;
13839
13884
  e.ptr = NULL;
13840
- e.depth = depth ? depth : 64;
13885
+ e.depth = depth ? depth : kUpb_WireFormat_DefaultDepthLimit;
13841
13886
  e.options = options;
13842
13887
  _upb_mapsorter_init(&e.sorter);
13843
13888
 
@@ -13924,3 +13969,6 @@ const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag,
13924
13969
  #undef UPB_DESCRIPTOR_UPB_H_FILENAME
13925
13970
  #undef UPB_DESC
13926
13971
  #undef UPB_IS_GOOGLE3
13972
+ #undef UPB_ATOMIC
13973
+ #undef UPB_USE_C11_ATOMICS
13974
+ #undef UPB_PRIVATE