google-protobuf 3.22.0.rc.2-x86_64-linux → 3.22.0.rc.3-x86_64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

@@ -641,14 +641,12 @@ static int (*const compar[kUpb_FieldType_SizeOf])(const void*, const void*) = {
641
641
  [kUpb_FieldType_Bytes] = _upb_mapsorter_cmpstr,
642
642
  };
643
643
 
644
- bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type,
645
- const upb_Map* map, _upb_sortedmap* sorted) {
646
- int map_size = _upb_Map_Size(map);
644
+ static bool _upb_mapsorter_resize(_upb_mapsorter* s, _upb_sortedmap* sorted,
645
+ int size) {
647
646
  sorted->start = s->size;
648
647
  sorted->pos = sorted->start;
649
- sorted->end = sorted->start + map_size;
648
+ sorted->end = sorted->start + size;
650
649
 
651
- // Grow s->entries if necessary.
652
650
  if (sorted->end > s->cap) {
653
651
  s->cap = upb_Log2CeilingSize(sorted->end);
654
652
  s->entries = realloc(s->entries, s->cap * sizeof(*s->entries));
@@ -656,9 +654,17 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type,
656
654
  }
657
655
 
658
656
  s->size = sorted->end;
657
+ return true;
658
+ }
659
+
660
+ bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type,
661
+ const upb_Map* map, _upb_sortedmap* sorted) {
662
+ int map_size = _upb_Map_Size(map);
663
+
664
+ if (!_upb_mapsorter_resize(s, sorted, map_size)) return false;
659
665
 
660
666
  // Copy non-empty entries from the table to s->entries.
661
- upb_tabent const** dst = &s->entries[sorted->start];
667
+ const void** dst = &s->entries[sorted->start];
662
668
  const upb_tabent* src = map->table.t.entries;
663
669
  const upb_tabent* end = src + upb_table_size(&map->table.t);
664
670
  for (; src < end; src++) {
@@ -674,6 +680,29 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter* s, upb_FieldType key_type,
674
680
  compar[key_type]);
675
681
  return true;
676
682
  }
683
+
684
+ static int _upb_mapsorter_cmpext(const void* _a, const void* _b) {
685
+ const upb_Message_Extension* const* a = _a;
686
+ const upb_Message_Extension* const* b = _b;
687
+ uint32_t a_num = (*a)->ext->field.number;
688
+ uint32_t b_num = (*b)->ext->field.number;
689
+ assert(a_num != b_num);
690
+ return a_num < b_num ? -1 : 1;
691
+ }
692
+
693
+ bool _upb_mapsorter_pushexts(_upb_mapsorter* s,
694
+ const upb_Message_Extension* exts, size_t count,
695
+ _upb_sortedmap* sorted) {
696
+ if (!_upb_mapsorter_resize(s, sorted, count)) return false;
697
+
698
+ for (size_t i = 0; i < count; i++) {
699
+ s->entries[sorted->start + i] = &exts[i];
700
+ }
701
+
702
+ qsort(&s->entries[sorted->start], count, sizeof(*s->entries),
703
+ _upb_mapsorter_cmpext);
704
+ return true;
705
+ }
677
706
  /* This file was generated by upbc (the upb compiler) from the input
678
707
  * file:
679
708
  *
@@ -1862,7 +1891,7 @@ char* upb_strdup2(const char* s, size_t len, upb_Arena* a) {
1862
1891
  n = len + 1;
1863
1892
  p = upb_Arena_Malloc(a, n);
1864
1893
  if (p) {
1865
- memcpy(p, s, len);
1894
+ if (len != 0) memcpy(p, s, len);
1866
1895
  p[len] = 0;
1867
1896
  }
1868
1897
  return p;
@@ -5448,6 +5477,7 @@ upb_FindUnknownRet upb_MiniTable_FindUnknown(const upb_Message* msg,
5448
5477
  return ret;
5449
5478
  }
5450
5479
 
5480
+ // Warning: See TODO(b/267655898)
5451
5481
  upb_UnknownToMessageRet upb_MiniTable_PromoteUnknownToMessage(
5452
5482
  upb_Message* msg, const upb_MiniTable* mini_table,
5453
5483
  const upb_MiniTableField* field, const upb_MiniTable* sub_mini_table,
@@ -5458,7 +5488,10 @@ upb_UnknownToMessageRet upb_MiniTable_PromoteUnknownToMessage(
5458
5488
  // Callers should check that message is not set first before calling
5459
5489
  // PromotoUnknownToMessage.
5460
5490
  UPB_ASSERT(mini_table->subs[field->submsg_index].submsg == sub_mini_table);
5461
- UPB_ASSERT(upb_Message_GetMessage(msg, field, NULL) == NULL);
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
+ }
5462
5495
  upb_UnknownToMessageRet ret;
5463
5496
  ret.status = kUpb_UnknownToMessage_Ok;
5464
5497
  do {
@@ -5486,6 +5519,9 @@ upb_UnknownToMessageRet upb_MiniTable_PromoteUnknownToMessage(
5486
5519
  }
5487
5520
  } while (unknown.status == kUpb_FindUnknown_Ok);
5488
5521
  if (message) {
5522
+ if (is_oneof) {
5523
+ *_upb_oneofcase_field(msg, field) = field->number;
5524
+ }
5489
5525
  upb_Message_SetMessage(msg, mini_table, field, message);
5490
5526
  ret.message = message;
5491
5527
  }
@@ -5807,6 +5843,38 @@ upb_FieldType upb_MiniTableField_Type(const upb_MiniTableField* field) {
5807
5843
  return field->descriptortype;
5808
5844
  }
5809
5845
 
5846
+ static bool upb_MiniTable_Is_Oneof(const upb_MiniTableField* f) {
5847
+ return f->presence < 0;
5848
+ }
5849
+
5850
+ const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m,
5851
+ const upb_MiniTableField* f) {
5852
+ if (UPB_UNLIKELY(!upb_MiniTable_Is_Oneof(f))) {
5853
+ return NULL;
5854
+ }
5855
+ const upb_MiniTableField* ptr = &m->fields[0];
5856
+ const upb_MiniTableField* end = &m->fields[m->field_count];
5857
+ while (++ptr < end) {
5858
+ if (ptr->presence == (*f).presence) {
5859
+ return ptr;
5860
+ }
5861
+ }
5862
+ return NULL;
5863
+ }
5864
+
5865
+ bool upb_MiniTable_NextOneofField(const upb_MiniTable* m,
5866
+ const upb_MiniTableField** f) {
5867
+ const upb_MiniTableField* ptr = *f;
5868
+ const upb_MiniTableField* end = &m->fields[m->field_count];
5869
+ while (++ptr < end) {
5870
+ if (ptr->presence == (*f)->presence) {
5871
+ *f = ptr;
5872
+ return true;
5873
+ }
5874
+ }
5875
+ return false;
5876
+ }
5877
+
5810
5878
 
5811
5879
  #include <inttypes.h>
5812
5880
  #include <stdlib.h>
@@ -6438,33 +6506,38 @@ static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) {
6438
6506
  d->table->size = UPB_ALIGN_UP(d->table->size, 8);
6439
6507
  }
6440
6508
 
6441
- static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data,
6442
- size_t len) {
6443
- if (len < 2) {
6444
- upb_MtDecoder_ErrorFormat(d, "Invalid map encode length: %zu", len);
6445
- UPB_UNREACHABLE();
6509
+ static void upb_MtDecoder_ValidateEntryField(upb_MtDecoder* d,
6510
+ const upb_MiniTableField* f,
6511
+ int expected_num) {
6512
+ const char* name = expected_num == 1 ? "key" : "val";
6513
+ if (f->number != expected_num) {
6514
+ upb_MtDecoder_ErrorFormat(d,
6515
+ "map %s did not have expected number (%d vs %d)",
6516
+ name, expected_num, (int)f->number);
6446
6517
  }
6447
- const upb_EncodedType key_type = _upb_FromBase92(data[0]);
6448
- switch (key_type) {
6449
- case kUpb_EncodedType_Fixed32:
6450
- case kUpb_EncodedType_Fixed64:
6451
- case kUpb_EncodedType_SFixed32:
6452
- case kUpb_EncodedType_SFixed64:
6453
- case kUpb_EncodedType_Int32:
6454
- case kUpb_EncodedType_UInt32:
6455
- case kUpb_EncodedType_SInt32:
6456
- case kUpb_EncodedType_Int64:
6457
- case kUpb_EncodedType_UInt64:
6458
- case kUpb_EncodedType_SInt64:
6459
- case kUpb_EncodedType_Bool:
6460
- case kUpb_EncodedType_String:
6461
- break;
6462
6518
 
6463
- default:
6464
- upb_MtDecoder_ErrorFormat(d, "Invalid map key field type: %d", key_type);
6465
- UPB_UNREACHABLE();
6519
+ if (upb_IsRepeatedOrMap(f)) {
6520
+ upb_MtDecoder_ErrorFormat(
6521
+ d, "map %s cannot be repeated or map, or be in oneof", name);
6522
+ }
6523
+
6524
+ uint32_t not_ok_types;
6525
+ if (expected_num == 1) {
6526
+ not_ok_types = (1 << kUpb_FieldType_Float) | (1 << kUpb_FieldType_Double) |
6527
+ (1 << kUpb_FieldType_Message) | (1 << kUpb_FieldType_Group) |
6528
+ (1 << kUpb_FieldType_Bytes) | (1 << kUpb_FieldType_Enum);
6529
+ } else {
6530
+ not_ok_types = 1 << kUpb_FieldType_Group;
6466
6531
  }
6467
6532
 
6533
+ if ((1 << upb_MiniTableField_Type(f)) & not_ok_types) {
6534
+ upb_MtDecoder_ErrorFormat(d, "map %s cannot have type %d", name,
6535
+ (int)f->descriptortype);
6536
+ }
6537
+ }
6538
+
6539
+ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data,
6540
+ size_t len) {
6468
6541
  upb_MtDecoder_ParseMessage(d, data, len);
6469
6542
  upb_MtDecoder_AssignHasbits(d->table);
6470
6543
 
@@ -6473,29 +6546,15 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data,
6473
6546
  UPB_UNREACHABLE();
6474
6547
  }
6475
6548
 
6476
- const int num0 = d->table->fields[0].number;
6477
- if (UPB_UNLIKELY(num0 != 1)) {
6478
- upb_MtDecoder_ErrorFormat(d, "field %d in map key", num0);
6479
- UPB_UNREACHABLE();
6480
- }
6481
-
6482
- const int num1 = d->table->fields[1].number;
6483
- if (UPB_UNLIKELY(num1 != 2)) {
6484
- upb_MtDecoder_ErrorFormat(d, "field %d in map val", num1);
6485
- UPB_UNREACHABLE();
6486
- }
6487
-
6488
- const int off0 = d->table->fields[0].offset;
6489
- if (UPB_UNLIKELY(off0 != kNoPresence && off0 != kHasbitPresence)) {
6490
- upb_MtDecoder_ErrorFormat(d, "bad offset %d in map key", off0);
6491
- UPB_UNREACHABLE();
6549
+ upb_LayoutItem* end = UPB_PTRADD(d->vec.data, d->vec.size);
6550
+ for (upb_LayoutItem* item = d->vec.data; item < end; item++) {
6551
+ if (item->type == kUpb_LayoutItemType_OneofCase) {
6552
+ upb_MtDecoder_ErrorFormat(d, "Map entry cannot have oneof");
6553
+ }
6492
6554
  }
6493
6555
 
6494
- const int off1 = d->table->fields[1].offset;
6495
- if (UPB_UNLIKELY(off1 != kNoPresence && off1 != kHasbitPresence)) {
6496
- upb_MtDecoder_ErrorFormat(d, "bad offset %d in map val", off1);
6497
- UPB_UNREACHABLE();
6498
- }
6556
+ upb_MtDecoder_ValidateEntryField(d, &d->table->fields[0], 1);
6557
+ upb_MtDecoder_ValidateEntryField(d, &d->table->fields[1], 2);
6499
6558
 
6500
6559
  // Map entries have a pre-determined layout, regardless of types.
6501
6560
  // NOTE: sync with mini_table/message_internal.h.
@@ -6752,14 +6811,28 @@ bool upb_MiniTable_SetSubMessage(upb_MiniTable* table,
6752
6811
  UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field &&
6753
6812
  (uintptr_t)field <
6754
6813
  (uintptr_t)(table->fields + table->field_count));
6755
- // TODO: check these type invariants at runtime and return error to the
6756
- // caller if they are violated, instead of using an assert.
6757
- UPB_ASSERT(field->descriptortype == kUpb_FieldType_Message ||
6758
- field->descriptortype == kUpb_FieldType_Group);
6759
- if (sub->ext & kUpb_ExtMode_IsMapEntry) {
6760
- UPB_ASSERT(field->descriptortype == kUpb_FieldType_Message);
6761
- field->mode = (field->mode & ~kUpb_FieldMode_Mask) | kUpb_FieldMode_Map;
6814
+ UPB_ASSERT(sub);
6815
+
6816
+ const bool sub_is_map = sub->ext & kUpb_ExtMode_IsMapEntry;
6817
+
6818
+ switch (field->descriptortype) {
6819
+ case kUpb_FieldType_Message:
6820
+ if (sub_is_map) {
6821
+ const bool table_is_map = table->ext & kUpb_ExtMode_IsMapEntry;
6822
+ if (UPB_UNLIKELY(table_is_map)) return false;
6823
+
6824
+ field->mode = (field->mode & ~kUpb_FieldMode_Mask) | kUpb_FieldMode_Map;
6825
+ }
6826
+ break;
6827
+
6828
+ case kUpb_FieldType_Group:
6829
+ if (UPB_UNLIKELY(sub_is_map)) return false;
6830
+ break;
6831
+
6832
+ default:
6833
+ return false;
6762
6834
  }
6835
+
6763
6836
  upb_MiniTableSub* table_sub = (void*)&table->subs[field->submsg_index];
6764
6837
  table_sub->submsg = sub;
6765
6838
  return true;
@@ -6770,6 +6843,8 @@ bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field,
6770
6843
  UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field &&
6771
6844
  (uintptr_t)field <
6772
6845
  (uintptr_t)(table->fields + table->field_count));
6846
+ UPB_ASSERT(sub);
6847
+
6773
6848
  upb_MiniTableSub* table_sub = (void*)&table->subs[field->submsg_index];
6774
6849
  table_sub->subenum = sub;
6775
6850
  return true;
@@ -7152,9 +7227,27 @@ void _upb_DefBuilder_OomErr(upb_DefBuilder* ctx) {
7152
7227
  _upb_DefBuilder_FailJmp(ctx);
7153
7228
  }
7154
7229
 
7230
+ // Verify a relative identifier string. The loop is branchless for speed.
7231
+ static void _upb_DefBuilder_CheckIdentNotFull(upb_DefBuilder* ctx,
7232
+ upb_StringView name) {
7233
+ bool good = name.size > 0;
7234
+
7235
+ for (size_t i = 0; i < name.size; i++) {
7236
+ const char c = name.data[i];
7237
+ const char d = c | 0x20; // force lowercase
7238
+ const bool is_alpha = (('a' <= d) & (d <= 'z')) | (c == '_');
7239
+ const bool is_numer = ('0' <= c) & (c <= '9') & (i != 0);
7240
+
7241
+ good &= is_alpha | is_numer;
7242
+ }
7243
+
7244
+ if (!good) _upb_DefBuilder_CheckIdentSlow(ctx, name, false);
7245
+ }
7246
+
7155
7247
  const char* _upb_DefBuilder_MakeFullName(upb_DefBuilder* ctx,
7156
7248
  const char* prefix,
7157
7249
  upb_StringView name) {
7250
+ _upb_DefBuilder_CheckIdentNotFull(ctx, name);
7158
7251
  if (prefix) {
7159
7252
  // ret = prefix + '.' + name;
7160
7253
  size_t n = strlen(prefix);
@@ -7270,7 +7363,7 @@ static bool TryGetChar(const char** src, const char* end, char* ch) {
7270
7363
  return true;
7271
7364
  }
7272
7365
 
7273
- static char TryGetHexDigit(const char** src, const char* end) {
7366
+ static int TryGetHexDigit(const char** src, const char* end) {
7274
7367
  char ch;
7275
7368
  if (!TryGetChar(src, end, &ch)) return -1;
7276
7369
  if ('0' <= ch && ch <= '9') {
@@ -7287,10 +7380,10 @@ static char TryGetHexDigit(const char** src, const char* end) {
7287
7380
  static char upb_DefBuilder_ParseHexEscape(upb_DefBuilder* ctx,
7288
7381
  const upb_FieldDef* f,
7289
7382
  const char** src, const char* end) {
7290
- char hex_digit = TryGetHexDigit(src, end);
7383
+ int hex_digit = TryGetHexDigit(src, end);
7291
7384
  if (hex_digit < 0) {
7292
7385
  _upb_DefBuilder_Errf(
7293
- ctx, "\\x cannot be followed by non-hex digit in field '%s' default",
7386
+ ctx, "\\x must be followed by at least one hex digit (field='%s')",
7294
7387
  upb_FieldDef_FullName(f));
7295
7388
  return 0;
7296
7389
  }
@@ -7466,7 +7559,7 @@ err:
7466
7559
  }
7467
7560
 
7468
7561
  bool _upb_DefPool_InsertExt(upb_DefPool* s, const upb_MiniTableExtension* ext,
7469
- upb_FieldDef* f) {
7562
+ const upb_FieldDef* f) {
7470
7563
  return upb_inttable_insert(&s->exts, (uintptr_t)ext, upb_value_constptr(f),
7471
7564
  s->arena);
7472
7565
  }
@@ -7698,12 +7791,6 @@ static const upb_FileDef* _upb_DefPool_AddFile(
7698
7791
  const upb_MiniTableFile* layout, upb_Status* status) {
7699
7792
  const upb_StringView name = UPB_DESC(FileDescriptorProto_name)(file_proto);
7700
7793
 
7701
- if (name.size == 0) {
7702
- upb_Status_SetErrorFormat(status,
7703
- "missing name in google_protobuf_FileDescriptorProto");
7704
- return NULL;
7705
- }
7706
-
7707
7794
  // Determine whether we already know about this file.
7708
7795
  {
7709
7796
  upb_value v;
@@ -7912,6 +7999,7 @@ struct upb_EnumDef {
7912
7999
  int res_range_count;
7913
8000
  int res_name_count;
7914
8001
  int32_t defaultval;
8002
+ bool is_closed;
7915
8003
  bool is_sorted; // Whether all of the values are defined in ascending order.
7916
8004
  };
7917
8005
 
@@ -7919,15 +8007,6 @@ upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i) {
7919
8007
  return (upb_EnumDef*)&e[i];
7920
8008
  }
7921
8009
 
7922
- // TODO: Maybe implement this on top of a ZCOS instead?
7923
- void _upb_EnumDef_Debug(const upb_EnumDef* e) {
7924
- fprintf(stderr, "enum %s (%p) {\n", e->full_name, e);
7925
- fprintf(stderr, " value_count: %d\n", e->value_count);
7926
- fprintf(stderr, " default: %d\n", e->defaultval);
7927
- fprintf(stderr, " is_sorted: %d\n", e->is_sorted);
7928
- fprintf(stderr, "}\n");
7929
- }
7930
-
7931
8010
  const upb_MiniTableEnum* _upb_EnumDef_MiniTable(const upb_EnumDef* e) {
7932
8011
  return e->layout;
7933
8012
  }
@@ -8023,10 +8102,7 @@ const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i) {
8023
8102
  return _upb_EnumValueDef_At(e->values, i);
8024
8103
  }
8025
8104
 
8026
- bool upb_EnumDef_IsClosed(const upb_EnumDef* e) {
8027
- if (UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3) return false;
8028
- return upb_FileDef_Syntax(e->file) == kUpb_Syntax_Proto2;
8029
- }
8105
+ bool upb_EnumDef_IsClosed(const upb_EnumDef* e) { return e->is_closed; }
8030
8106
 
8031
8107
  bool upb_EnumDef_MiniDescriptorEncode(const upb_EnumDef* e, upb_Arena* a,
8032
8108
  upb_StringView* out) {
@@ -8106,12 +8182,14 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix,
8106
8182
  e->file = _upb_DefBuilder_File(ctx);
8107
8183
 
8108
8184
  name = UPB_DESC(EnumDescriptorProto_name)(enum_proto);
8109
- _upb_DefBuilder_CheckIdentNotFull(ctx, name);
8110
8185
 
8111
8186
  e->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name);
8112
8187
  _upb_DefBuilder_Add(ctx, e->full_name,
8113
8188
  _upb_DefType_Pack(e, UPB_DEFTYPE_ENUM));
8114
8189
 
8190
+ e->is_closed = (!UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3) &&
8191
+ (upb_FileDef_Syntax(e->file) == kUpb_Syntax_Proto2);
8192
+
8115
8193
  values = UPB_DESC(EnumDescriptorProto_value)(enum_proto, &n_value);
8116
8194
 
8117
8195
  bool ok = upb_strtable_init(&e->ntoi, n_value, ctx->arena);
@@ -8144,7 +8222,7 @@ static void create_enumdef(upb_DefBuilder* ctx, const char* prefix,
8144
8222
 
8145
8223
  upb_inttable_compact(&e->iton, ctx->arena);
8146
8224
 
8147
- if (upb_FileDef_Syntax(e->file) == kUpb_Syntax_Proto2) {
8225
+ if (e->is_closed) {
8148
8226
  if (ctx->layout) {
8149
8227
  UPB_ASSERT(ctx->enum_count < ctx->layout->enum_count);
8150
8228
  e->layout = ctx->layout->enums[ctx->enum_count++];
@@ -8443,10 +8521,11 @@ struct upb_FieldDef {
8443
8521
  uint16_t index_;
8444
8522
  uint16_t layout_index; // Index into msgdef->layout->fields or file->exts
8445
8523
  bool has_default;
8446
- bool is_extension_;
8447
- bool is_packed_;
8448
- bool proto3_optional_;
8449
- bool has_json_name_;
8524
+ bool has_json_name;
8525
+ bool has_presence;
8526
+ bool is_extension;
8527
+ bool is_packed;
8528
+ bool is_proto3_optional;
8450
8529
  upb_FieldType type_;
8451
8530
  upb_Label label_;
8452
8531
  #if UINTPTR_MAX == 0xffffffff
@@ -8513,11 +8592,9 @@ upb_Label upb_FieldDef_Label(const upb_FieldDef* f) { return f->label_; }
8513
8592
 
8514
8593
  uint32_t upb_FieldDef_Number(const upb_FieldDef* f) { return f->number_; }
8515
8594
 
8516
- bool upb_FieldDef_IsExtension(const upb_FieldDef* f) {
8517
- return f->is_extension_;
8518
- }
8595
+ bool upb_FieldDef_IsExtension(const upb_FieldDef* f) { return f->is_extension; }
8519
8596
 
8520
- bool upb_FieldDef_IsPacked(const upb_FieldDef* f) { return f->is_packed_; }
8597
+ bool upb_FieldDef_IsPacked(const upb_FieldDef* f) { return f->is_packed; }
8521
8598
 
8522
8599
  const char* upb_FieldDef_Name(const upb_FieldDef* f) {
8523
8600
  return _upb_DefBuilder_FullToShort(f->full_name);
@@ -8528,7 +8605,7 @@ const char* upb_FieldDef_JsonName(const upb_FieldDef* f) {
8528
8605
  }
8529
8606
 
8530
8607
  bool upb_FieldDef_HasJsonName(const upb_FieldDef* f) {
8531
- return f->has_json_name_;
8608
+ return f->has_json_name;
8532
8609
  }
8533
8610
 
8534
8611
  const upb_FileDef* upb_FieldDef_File(const upb_FieldDef* f) { return f->file; }
@@ -8538,11 +8615,11 @@ const upb_MessageDef* upb_FieldDef_ContainingType(const upb_FieldDef* f) {
8538
8615
  }
8539
8616
 
8540
8617
  const upb_MessageDef* upb_FieldDef_ExtensionScope(const upb_FieldDef* f) {
8541
- return f->is_extension_ ? f->scope.extension_scope : NULL;
8618
+ return f->is_extension ? f->scope.extension_scope : NULL;
8542
8619
  }
8543
8620
 
8544
8621
  const upb_OneofDef* upb_FieldDef_ContainingOneof(const upb_FieldDef* f) {
8545
- return f->is_extension_ ? NULL : f->scope.oneof;
8622
+ return f->is_extension ? NULL : f->scope.oneof;
8546
8623
  }
8547
8624
 
8548
8625
  const upb_OneofDef* upb_FieldDef_RealContainingOneof(const upb_FieldDef* f) {
@@ -8619,22 +8696,18 @@ const upb_MiniTableExtension* _upb_FieldDef_ExtensionMiniTable(
8619
8696
  }
8620
8697
 
8621
8698
  bool _upb_FieldDef_IsClosedEnum(const upb_FieldDef* f) {
8622
- if (UPB_TREAT_PROTO2_ENUMS_LIKE_PROTO3) return false;
8623
8699
  if (f->type_ != kUpb_FieldType_Enum) return false;
8624
-
8625
- // TODO: Maybe make is_proto2 a bool at creation?
8626
- const upb_FileDef* file = upb_EnumDef_File(f->sub.enumdef);
8627
- return upb_FileDef_Syntax(file) == kUpb_Syntax_Proto2;
8700
+ return upb_EnumDef_IsClosed(f->sub.enumdef);
8628
8701
  }
8629
8702
 
8630
8703
  bool _upb_FieldDef_IsProto3Optional(const upb_FieldDef* f) {
8631
- return f->proto3_optional_;
8704
+ return f->is_proto3_optional;
8632
8705
  }
8633
8706
 
8634
8707
  int _upb_FieldDef_LayoutIndex(const upb_FieldDef* f) { return f->layout_index; }
8635
8708
 
8636
8709
  uint64_t _upb_FieldDef_Modifiers(const upb_FieldDef* f) {
8637
- uint64_t out = f->is_packed_ ? kUpb_FieldModifier_IsPacked : 0;
8710
+ uint64_t out = f->is_packed ? kUpb_FieldModifier_IsPacked : 0;
8638
8711
 
8639
8712
  switch (f->label_) {
8640
8713
  case kUpb_Label_Optional:
@@ -8657,13 +8730,7 @@ uint64_t _upb_FieldDef_Modifiers(const upb_FieldDef* f) {
8657
8730
  }
8658
8731
 
8659
8732
  bool upb_FieldDef_HasDefault(const upb_FieldDef* f) { return f->has_default; }
8660
-
8661
- bool upb_FieldDef_HasPresence(const upb_FieldDef* f) {
8662
- if (upb_FieldDef_IsRepeated(f)) return false;
8663
- const upb_FileDef* file = upb_FieldDef_File(f);
8664
- return upb_FieldDef_IsSubMessage(f) || upb_FieldDef_ContainingOneof(f) ||
8665
- upb_FileDef_Syntax(file) == kUpb_Syntax_Proto2;
8666
- }
8733
+ bool upb_FieldDef_HasPresence(const upb_FieldDef* f) { return f->has_presence; }
8667
8734
 
8668
8735
  bool upb_FieldDef_HasSubDef(const upb_FieldDef* f) {
8669
8736
  return upb_FieldDef_IsSubMessage(f) ||
@@ -8924,10 +8991,17 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix,
8924
8991
  }
8925
8992
 
8926
8993
  const upb_StringView name = UPB_DESC(FieldDescriptorProto_name)(field_proto);
8927
- _upb_DefBuilder_CheckIdentNotFull(ctx, name);
8928
8994
 
8929
- f->has_json_name_ = UPB_DESC(FieldDescriptorProto_has_json_name)(field_proto);
8930
- if (f->has_json_name_) {
8995
+ f->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name);
8996
+ f->label_ = (int)UPB_DESC(FieldDescriptorProto_label)(field_proto);
8997
+ f->number_ = UPB_DESC(FieldDescriptorProto_number)(field_proto);
8998
+ f->is_proto3_optional =
8999
+ UPB_DESC(FieldDescriptorProto_proto3_optional)(field_proto);
9000
+ f->msgdef = m;
9001
+ f->scope.oneof = NULL;
9002
+
9003
+ f->has_json_name = UPB_DESC(FieldDescriptorProto_has_json_name)(field_proto);
9004
+ if (f->has_json_name) {
8931
9005
  const upb_StringView sv =
8932
9006
  UPB_DESC(FieldDescriptorProto_json_name)(field_proto);
8933
9007
  f->json_name = upb_strdup2(sv.data, sv.size, ctx->arena);
@@ -8936,14 +9010,6 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix,
8936
9010
  }
8937
9011
  if (!f->json_name) _upb_DefBuilder_OomErr(ctx);
8938
9012
 
8939
- f->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name);
8940
- f->label_ = (int)UPB_DESC(FieldDescriptorProto_label)(field_proto);
8941
- f->number_ = UPB_DESC(FieldDescriptorProto_number)(field_proto);
8942
- f->proto3_optional_ =
8943
- UPB_DESC(FieldDescriptorProto_proto3_optional)(field_proto);
8944
- f->msgdef = m;
8945
- f->scope.oneof = NULL;
8946
-
8947
9013
  const bool has_type = UPB_DESC(FieldDescriptorProto_has_type)(field_proto);
8948
9014
  const bool has_type_name =
8949
9015
  UPB_DESC(FieldDescriptorProto_has_type_name)(field_proto);
@@ -9021,21 +9087,26 @@ static void _upb_FieldDef_Create(upb_DefBuilder* ctx, const char* prefix,
9021
9087
  UPB_DEF_SET_OPTIONS(f->opts, FieldDescriptorProto, FieldOptions, field_proto);
9022
9088
 
9023
9089
  if (UPB_DESC(FieldOptions_has_packed)(f->opts)) {
9024
- f->is_packed_ = UPB_DESC(FieldOptions_packed)(f->opts);
9090
+ f->is_packed = UPB_DESC(FieldOptions_packed)(f->opts);
9025
9091
  } else {
9026
9092
  // Repeated fields default to packed for proto3 only.
9027
- f->is_packed_ = upb_FieldDef_IsPrimitive(f) &&
9028
- f->label_ == kUpb_Label_Repeated &&
9029
- upb_FileDef_Syntax(f->file) == kUpb_Syntax_Proto3;
9093
+ f->is_packed = upb_FieldDef_IsPrimitive(f) &&
9094
+ f->label_ == kUpb_Label_Repeated &&
9095
+ upb_FileDef_Syntax(f->file) == kUpb_Syntax_Proto3;
9030
9096
  }
9097
+
9098
+ f->has_presence =
9099
+ (!upb_FieldDef_IsRepeated(f)) &&
9100
+ (upb_FieldDef_IsSubMessage(f) || upb_FieldDef_ContainingOneof(f) ||
9101
+ (upb_FileDef_Syntax(f->file) == kUpb_Syntax_Proto2));
9031
9102
  }
9032
9103
 
9033
9104
  static void _upb_FieldDef_CreateExt(upb_DefBuilder* ctx, const char* prefix,
9034
9105
  const UPB_DESC(FieldDescriptorProto) *
9035
9106
  field_proto,
9036
9107
  upb_MessageDef* m, upb_FieldDef* f) {
9108
+ f->is_extension = true;
9037
9109
  _upb_FieldDef_Create(ctx, prefix, field_proto, m, f);
9038
- f->is_extension_ = true;
9039
9110
 
9040
9111
  if (UPB_DESC(FieldDescriptorProto_has_oneof_index)(field_proto)) {
9041
9112
  _upb_DefBuilder_Errf(ctx, "oneof_index provided for extension field (%s)",
@@ -9055,11 +9126,11 @@ static void _upb_FieldDef_CreateNotExt(upb_DefBuilder* ctx, const char* prefix,
9055
9126
  const UPB_DESC(FieldDescriptorProto) *
9056
9127
  field_proto,
9057
9128
  upb_MessageDef* m, upb_FieldDef* f) {
9129
+ f->is_extension = false;
9058
9130
  _upb_FieldDef_Create(ctx, prefix, field_proto, m, f);
9059
- f->is_extension_ = false;
9060
9131
 
9061
9132
  if (!UPB_DESC(FieldDescriptorProto_has_oneof_index)(field_proto)) {
9062
- if (f->proto3_optional_) {
9133
+ if (f->is_proto3_optional) {
9063
9134
  _upb_DefBuilder_Errf(
9064
9135
  ctx,
9065
9136
  "non-extension field (%s) with proto3_optional was not in a oneof",
@@ -9068,19 +9139,24 @@ static void _upb_FieldDef_CreateNotExt(upb_DefBuilder* ctx, const char* prefix,
9068
9139
  }
9069
9140
 
9070
9141
  _upb_MessageDef_InsertField(ctx, m, f);
9142
+ }
9071
9143
 
9072
- if (!ctx->layout) return;
9144
+ upb_FieldDef* _upb_Extensions_New(
9145
+ upb_DefBuilder* ctx, int n,
9146
+ const UPB_DESC(FieldDescriptorProto) * const* protos, const char* prefix,
9147
+ upb_MessageDef* m) {
9148
+ _upb_DefType_CheckPadding(sizeof(upb_FieldDef));
9149
+ upb_FieldDef* defs =
9150
+ (upb_FieldDef*)_upb_DefBuilder_Alloc(ctx, sizeof(upb_FieldDef) * n);
9073
9151
 
9074
- const upb_MiniTable* mt = upb_MessageDef_MiniTable(m);
9075
- const upb_MiniTableField* fields = mt->fields;
9076
- for (int i = 0; i < mt->field_count; i++) {
9077
- if (fields[i].number == f->number_) {
9078
- f->layout_index = i;
9079
- return;
9080
- }
9152
+ for (int i = 0; i < n; i++) {
9153
+ upb_FieldDef* f = &defs[i];
9154
+
9155
+ _upb_FieldDef_CreateExt(ctx, prefix, protos[i], m, f);
9156
+ f->index_ = i;
9081
9157
  }
9082
9158
 
9083
- UPB_ASSERT(false); // It should be impossible to reach this point.
9159
+ return defs;
9084
9160
  }
9085
9161
 
9086
9162
  upb_FieldDef* _upb_FieldDefs_New(
@@ -9091,28 +9167,23 @@ upb_FieldDef* _upb_FieldDefs_New(
9091
9167
  upb_FieldDef* defs =
9092
9168
  (upb_FieldDef*)_upb_DefBuilder_Alloc(ctx, sizeof(upb_FieldDef) * n);
9093
9169
 
9094
- // If we are creating extensions then is_sorted will be NULL.
9095
- // If we are not creating extensions then is_sorted will be non-NULL.
9096
- if (is_sorted) {
9097
- uint32_t previous = 0;
9098
- for (int i = 0; i < n; i++) {
9099
- upb_FieldDef* f = &defs[i];
9100
-
9101
- _upb_FieldDef_CreateNotExt(ctx, prefix, protos[i], m, f);
9102
- f->index_ = i;
9103
- if (!ctx->layout) f->layout_index = i;
9104
-
9105
- const uint32_t current = f->number_;
9106
- if (previous > current) *is_sorted = false;
9107
- previous = current;
9170
+ uint32_t previous = 0;
9171
+ for (int i = 0; i < n; i++) {
9172
+ upb_FieldDef* f = &defs[i];
9173
+
9174
+ _upb_FieldDef_CreateNotExt(ctx, prefix, protos[i], m, f);
9175
+ f->index_ = i;
9176
+ if (!ctx->layout) {
9177
+ // Speculate that the def fields are sorted. We will always sort the
9178
+ // MiniTable fields, so if defs are sorted then indices will match.
9179
+ //
9180
+ // If this is incorrect, we will overwrite later.
9181
+ f->layout_index = i;
9108
9182
  }
9109
- } else {
9110
- for (int i = 0; i < n; i++) {
9111
- upb_FieldDef* f = &defs[i];
9112
9183
 
9113
- _upb_FieldDef_CreateExt(ctx, prefix, protos[i], m, f);
9114
- f->index_ = i;
9115
- }
9184
+ const uint32_t current = f->number_;
9185
+ if (previous > current) *is_sorted = false;
9186
+ previous = current;
9116
9187
  }
9117
9188
 
9118
9189
  return defs;
@@ -9168,9 +9239,12 @@ static int _upb_FieldDef_Compare(const void* p1, const void* p2) {
9168
9239
  return (v1 < v2) ? -1 : (v1 > v2);
9169
9240
  }
9170
9241
 
9242
+ // _upb_FieldDefs_Sorted() is mostly a pure function of its inputs, but has one
9243
+ // critical side effect that we depend on: it sets layout_index appropriately
9244
+ // for non-sorted lists of fields.
9171
9245
  const upb_FieldDef** _upb_FieldDefs_Sorted(const upb_FieldDef* f, int n,
9172
9246
  upb_Arena* a) {
9173
- // TODO: Try to replace this arena alloc with a persistent scratch buffer.
9247
+ // TODO(salo): Replace this arena alloc with a persistent scratch buffer.
9174
9248
  upb_FieldDef** out = (upb_FieldDef**)upb_Arena_Malloc(a, n * sizeof(void*));
9175
9249
  if (!out) return NULL;
9176
9250
 
@@ -9187,7 +9261,7 @@ const upb_FieldDef** _upb_FieldDefs_Sorted(const upb_FieldDef* f, int n,
9187
9261
 
9188
9262
  bool upb_FieldDef_MiniDescriptorEncode(const upb_FieldDef* f, upb_Arena* a,
9189
9263
  upb_StringView* out) {
9190
- UPB_ASSERT(f->is_extension_);
9264
+ UPB_ASSERT(f->is_extension);
9191
9265
 
9192
9266
  upb_DescState s;
9193
9267
  _upb_DescState_Init(&s);
@@ -9225,7 +9299,10 @@ static void resolve_extension(upb_DefBuilder* ctx, const char* prefix,
9225
9299
  "field number %u in extension %s has no extension range in message %s",
9226
9300
  (unsigned)f->number_, f->full_name, upb_MessageDef_FullName(m));
9227
9301
  }
9302
+ }
9228
9303
 
9304
+ void _upb_FieldDef_BuildMiniTableExtension(upb_DefBuilder* ctx,
9305
+ const upb_FieldDef* f) {
9229
9306
  const upb_MiniTableExtension* ext = _upb_FieldDef_ExtensionMiniTable(f);
9230
9307
 
9231
9308
  if (ctx->layout) {
@@ -9244,8 +9321,8 @@ static void resolve_extension(upb_DefBuilder* ctx, const char* prefix,
9244
9321
  sub.subenum = _upb_EnumDef_MiniTable(f->sub.enumdef);
9245
9322
  }
9246
9323
  bool ok2 = upb_MiniTableExtension_Build(desc.data, desc.size, mut_ext,
9247
- upb_MessageDef_MiniTable(m), sub,
9248
- ctx->status);
9324
+ upb_MessageDef_MiniTable(f->msgdef),
9325
+ sub, ctx->status);
9249
9326
  if (!ok2) _upb_DefBuilder_Errf(ctx, "Could not build extension mini table");
9250
9327
  }
9251
9328
 
@@ -9290,7 +9367,7 @@ void _upb_FieldDef_Resolve(upb_DefBuilder* ctx, const char* prefix,
9290
9367
  resolve_subdef(ctx, prefix, f);
9291
9368
  resolve_default(ctx, f, field_proto);
9292
9369
 
9293
- if (f->is_extension_) {
9370
+ if (f->is_extension) {
9294
9371
  resolve_extension(ctx, prefix, f, field_proto);
9295
9372
  }
9296
9373
  }
@@ -9302,6 +9379,7 @@ struct upb_FileDef {
9302
9379
  const UPB_DESC(FileOptions) * opts;
9303
9380
  const char* name;
9304
9381
  const char* package;
9382
+ const char* edition;
9305
9383
 
9306
9384
  const upb_FileDef** deps;
9307
9385
  const int32_t* public_deps;
@@ -9338,6 +9416,10 @@ const char* upb_FileDef_Package(const upb_FileDef* f) {
9338
9416
  return f->package ? f->package : "";
9339
9417
  }
9340
9418
 
9419
+ const char* upb_FileDef_Edition(const upb_FileDef* f) {
9420
+ return f->edition ? f->edition : "";
9421
+ }
9422
+
9341
9423
  const char* _upb_FileDef_RawPackage(const upb_FileDef* f) { return f->package; }
9342
9424
 
9343
9425
  upb_Syntax upb_FileDef_Syntax(const upb_FileDef* f) { return f->syntax; }
@@ -9485,13 +9567,14 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx,
9485
9567
  }
9486
9568
  }
9487
9569
 
9488
- if (!UPB_DESC(FileDescriptorProto_has_name)(file_proto)) {
9489
- _upb_DefBuilder_Errf(ctx, "File has no name");
9570
+ upb_StringView name = UPB_DESC(FileDescriptorProto_name)(file_proto);
9571
+ file->name = strviewdup(ctx, name);
9572
+ if (strlen(file->name) != name.size) {
9573
+ _upb_DefBuilder_Errf(ctx, "File name contained embedded NULL");
9490
9574
  }
9491
9575
 
9492
- file->name = strviewdup(ctx, UPB_DESC(FileDescriptorProto_name)(file_proto));
9493
-
9494
9576
  upb_StringView package = UPB_DESC(FileDescriptorProto_package)(file_proto);
9577
+
9495
9578
  if (package.size) {
9496
9579
  _upb_DefBuilder_CheckIdentFull(ctx, package);
9497
9580
  file->package = strviewdup(ctx, package);
@@ -9499,6 +9582,18 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx,
9499
9582
  file->package = NULL;
9500
9583
  }
9501
9584
 
9585
+ upb_StringView edition = UPB_DESC(FileDescriptorProto_edition)(file_proto);
9586
+
9587
+ if (edition.size == 0) {
9588
+ file->edition = NULL;
9589
+ } else {
9590
+ // TODO(b/267770604): How should we validate this?
9591
+ file->edition = strviewdup(ctx, edition);
9592
+ if (strlen(file->edition) != edition.size) {
9593
+ _upb_DefBuilder_Errf(ctx, "Edition name contained embedded NULL");
9594
+ }
9595
+ }
9596
+
9502
9597
  if (UPB_DESC(FileDescriptorProto_has_syntax)(file_proto)) {
9503
9598
  upb_StringView syntax = UPB_DESC(FileDescriptorProto_syntax)(file_proto);
9504
9599
 
@@ -9567,8 +9662,7 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx,
9567
9662
  // Create extensions.
9568
9663
  exts = UPB_DESC(FileDescriptorProto_extension)(file_proto, &n);
9569
9664
  file->top_lvl_ext_count = n;
9570
- file->top_lvl_exts =
9571
- _upb_FieldDefs_New(ctx, n, exts, file->package, NULL, NULL);
9665
+ file->top_lvl_exts = _upb_Extensions_New(ctx, n, exts, file->package, NULL);
9572
9666
 
9573
9667
  // Create messages.
9574
9668
  msgs = UPB_DESC(FileDescriptorProto_message_type)(file_proto, &n);
@@ -9592,11 +9686,19 @@ void _upb_FileDef_Create(upb_DefBuilder* ctx,
9592
9686
  _upb_FieldDef_Resolve(ctx, file->package, f);
9593
9687
  }
9594
9688
 
9595
- if (!ctx->layout) {
9596
- for (int i = 0; i < file->top_lvl_msg_count; i++) {
9597
- upb_MessageDef* m = (upb_MessageDef*)upb_FileDef_TopLevelMessage(file, i);
9598
- _upb_MessageDef_LinkMiniTable(ctx, m);
9599
- }
9689
+ for (int i = 0; i < file->top_lvl_msg_count; i++) {
9690
+ upb_MessageDef* m = (upb_MessageDef*)upb_FileDef_TopLevelMessage(file, i);
9691
+ _upb_MessageDef_CreateMiniTable(ctx, (upb_MessageDef*)m);
9692
+ }
9693
+
9694
+ for (int i = 0; i < file->top_lvl_ext_count; i++) {
9695
+ upb_FieldDef* f = (upb_FieldDef*)upb_FileDef_TopLevelExtension(file, i);
9696
+ _upb_FieldDef_BuildMiniTableExtension(ctx, f);
9697
+ }
9698
+
9699
+ for (int i = 0; i < file->top_lvl_msg_count; i++) {
9700
+ upb_MessageDef* m = (upb_MessageDef*)upb_FileDef_TopLevelMessage(file, i);
9701
+ _upb_MessageDef_LinkMiniTable(ctx, m);
9600
9702
  }
9601
9703
 
9602
9704
  if (file->ext_count) {
@@ -10109,6 +10211,8 @@ bool upb_MessageDef_IsMessageSet(const upb_MessageDef* m) {
10109
10211
  static upb_MiniTable* _upb_MessageDef_MakeMiniTable(upb_DefBuilder* ctx,
10110
10212
  const upb_MessageDef* m) {
10111
10213
  upb_StringView desc;
10214
+ // Note: this will assign layout_index for fields, so upb_FieldDef_MiniTable()
10215
+ // is safe to call only after this call.
10112
10216
  bool ok = upb_MessageDef_MiniDescriptorEncode(m, ctx->tmp_arena, &desc);
10113
10217
  if (!ok) _upb_DefBuilder_OomErr(ctx);
10114
10218
 
@@ -10128,23 +10232,6 @@ void _upb_MessageDef_Resolve(upb_DefBuilder* ctx, upb_MessageDef* m) {
10128
10232
  _upb_FieldDef_Resolve(ctx, m->full_name, f);
10129
10233
  }
10130
10234
 
10131
- if (!ctx->layout) {
10132
- m->layout = _upb_MessageDef_MakeMiniTable(ctx, m);
10133
- if (!m->layout) _upb_DefBuilder_OomErr(ctx);
10134
- }
10135
-
10136
- #ifndef NDEBUG
10137
- for (int i = 0; i < m->field_count; i++) {
10138
- const upb_FieldDef* f = upb_MessageDef_Field(m, i);
10139
- const int layout_index = _upb_FieldDef_LayoutIndex(f);
10140
- UPB_ASSERT(layout_index < m->layout->field_count);
10141
- const upb_MiniTableField* mt_f = &m->layout->fields[layout_index];
10142
- UPB_ASSERT(upb_FieldDef_Type(f) == upb_MiniTableField_Type(mt_f));
10143
- UPB_ASSERT(upb_FieldDef_HasPresence(f) ==
10144
- upb_MiniTableField_HasPresence(mt_f));
10145
- }
10146
- #endif
10147
-
10148
10235
  m->in_message_set = false;
10149
10236
  for (int i = 0; i < upb_MessageDef_NestedExtensionCount(m); i++) {
10150
10237
  upb_FieldDef* ext = (upb_FieldDef*)upb_MessageDef_NestedExtension(m, i);
@@ -10207,8 +10294,39 @@ void _upb_MessageDef_InsertField(upb_DefBuilder* ctx, upb_MessageDef* m,
10207
10294
  if (!ok) _upb_DefBuilder_OomErr(ctx);
10208
10295
  }
10209
10296
 
10297
+ void _upb_MessageDef_CreateMiniTable(upb_DefBuilder* ctx, upb_MessageDef* m) {
10298
+ if (ctx->layout == NULL) {
10299
+ m->layout = _upb_MessageDef_MakeMiniTable(ctx, m);
10300
+ } else {
10301
+ UPB_ASSERT(ctx->msg_count < ctx->layout->msg_count);
10302
+ m->layout = ctx->layout->msgs[ctx->msg_count++];
10303
+ UPB_ASSERT(m->field_count == m->layout->field_count);
10304
+
10305
+ // We don't need the result of this call, but it will assign layout_index
10306
+ // for all the fields in O(n lg n) time.
10307
+ _upb_FieldDefs_Sorted(m->fields, m->field_count, ctx->tmp_arena);
10308
+ }
10309
+
10310
+ for (int i = 0; i < m->nested_msg_count; i++) {
10311
+ upb_MessageDef* nested =
10312
+ (upb_MessageDef*)upb_MessageDef_NestedMessage(m, i);
10313
+ _upb_MessageDef_CreateMiniTable(ctx, nested);
10314
+ }
10315
+ }
10316
+
10210
10317
  void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx,
10211
10318
  const upb_MessageDef* m) {
10319
+ for (int i = 0; i < upb_MessageDef_NestedExtensionCount(m); i++) {
10320
+ const upb_FieldDef* ext = upb_MessageDef_NestedExtension(m, i);
10321
+ _upb_FieldDef_BuildMiniTableExtension(ctx, ext);
10322
+ }
10323
+
10324
+ for (int i = 0; i < m->nested_msg_count; i++) {
10325
+ _upb_MessageDef_LinkMiniTable(ctx, upb_MessageDef_NestedMessage(m, i));
10326
+ }
10327
+
10328
+ if (ctx->layout) return;
10329
+
10212
10330
  for (int i = 0; i < m->field_count; i++) {
10213
10331
  const upb_FieldDef* f = upb_MessageDef_Field(m, i);
10214
10332
  const upb_MessageDef* sub_m = upb_FieldDef_MessageSubDef(f);
@@ -10236,9 +10354,17 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx,
10236
10354
  }
10237
10355
  }
10238
10356
 
10239
- for (int i = 0; i < m->nested_msg_count; i++) {
10240
- _upb_MessageDef_LinkMiniTable(ctx, upb_MessageDef_NestedMessage(m, i));
10357
+ #ifndef NDEBUG
10358
+ for (int i = 0; i < m->field_count; i++) {
10359
+ const upb_FieldDef* f = upb_MessageDef_Field(m, i);
10360
+ const int layout_index = _upb_FieldDef_LayoutIndex(f);
10361
+ UPB_ASSERT(layout_index < m->layout->field_count);
10362
+ const upb_MiniTableField* mt_f = &m->layout->fields[layout_index];
10363
+ UPB_ASSERT(upb_FieldDef_Type(f) == upb_MiniTableField_Type(mt_f));
10364
+ UPB_ASSERT(upb_FieldDef_HasPresence(f) ==
10365
+ upb_MiniTableField_HasPresence(mt_f));
10241
10366
  }
10367
+ #endif
10242
10368
  }
10243
10369
 
10244
10370
  static uint64_t _upb_MessageDef_Modifiers(const upb_MessageDef* m) {
@@ -10371,7 +10497,6 @@ static void create_msgdef(upb_DefBuilder* ctx, const char* prefix,
10371
10497
  m->is_sorted = true;
10372
10498
 
10373
10499
  name = UPB_DESC(DescriptorProto_name)(msg_proto);
10374
- _upb_DefBuilder_CheckIdentNotFull(ctx, name);
10375
10500
 
10376
10501
  m->full_name = _upb_DefBuilder_MakeFullName(ctx, prefix, name);
10377
10502
  _upb_DefBuilder_Add(ctx, m->full_name, _upb_DefType_Pack(m, UPB_DEFTYPE_MSG));
@@ -10390,17 +10515,6 @@ static void create_msgdef(upb_DefBuilder* ctx, const char* prefix,
10390
10515
  ok = upb_strtable_init(&m->ntof, n_oneof + n_field, ctx->arena);
10391
10516
  if (!ok) _upb_DefBuilder_OomErr(ctx);
10392
10517
 
10393
- if (ctx->layout) {
10394
- /* create_fielddef() below depends on this being set. */
10395
- UPB_ASSERT(ctx->msg_count < ctx->layout->msg_count);
10396
- m->layout = ctx->layout->msgs[ctx->msg_count++];
10397
- UPB_ASSERT(n_field == m->layout->field_count);
10398
- } else {
10399
- /* Allocate now (to allow cross-linking), populate later. */
10400
- m->layout = _upb_DefBuilder_Alloc(
10401
- ctx, sizeof(*m->layout) + sizeof(_upb_FastTable_Entry));
10402
- }
10403
-
10404
10518
  UPB_DEF_SET_OPTIONS(m->opts, DescriptorProto, MessageOptions, msg_proto);
10405
10519
 
10406
10520
  m->oneof_count = n_oneof;
@@ -10441,7 +10555,7 @@ static void create_msgdef(upb_DefBuilder* ctx, const char* prefix,
10441
10555
  const UPB_DESC(FieldDescriptorProto)* const* exts =
10442
10556
  UPB_DESC(DescriptorProto_extension)(msg_proto, &n_ext);
10443
10557
  m->nested_ext_count = n_ext;
10444
- m->nested_exts = _upb_FieldDefs_New(ctx, n_ext, exts, m->full_name, m, NULL);
10558
+ m->nested_exts = _upb_Extensions_New(ctx, n_ext, exts, m->full_name, m);
10445
10559
 
10446
10560
  const UPB_DESC(DescriptorProto)* const* msgs =
10447
10561
  UPB_DESC(DescriptorProto_nested_type)(msg_proto, &n_msg);
@@ -10848,7 +10962,6 @@ static void create_service(upb_DefBuilder* ctx,
10848
10962
  s->file = _upb_DefBuilder_File(ctx);
10849
10963
 
10850
10964
  name = UPB_DESC(ServiceDescriptorProto_name)(svc_proto);
10851
- _upb_DefBuilder_CheckIdentNotFull(ctx, name);
10852
10965
  const char* package = _upb_FileDef_RawPackage(s->file);
10853
10966
  s->full_name = _upb_DefBuilder_MakeFullName(ctx, package, name);
10854
10967
  _upb_DefBuilder_Add(ctx, s->full_name,
@@ -11420,33 +11533,48 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr,
11420
11533
  upb_Map** map_p = UPB_PTR_AT(msg, field->offset, upb_Map*);
11421
11534
  upb_Map* map = *map_p;
11422
11535
  upb_MapEntry ent;
11536
+ UPB_ASSERT(upb_MiniTableField_Type(field) == kUpb_FieldType_Message);
11423
11537
  const upb_MiniTable* entry = subs[field->submsg_index].submsg;
11424
11538
 
11539
+ UPB_ASSERT(entry->field_count == 2);
11540
+ UPB_ASSERT(!upb_IsRepeatedOrMap(&entry->fields[0]));
11541
+ UPB_ASSERT(!upb_IsRepeatedOrMap(&entry->fields[1]));
11542
+
11425
11543
  if (!map) {
11426
11544
  map = _upb_Decoder_CreateMap(d, entry);
11427
11545
  *map_p = map;
11428
11546
  }
11429
11547
 
11430
- /* Parse map entry. */
11548
+ // Parse map entry.
11431
11549
  memset(&ent, 0, sizeof(ent));
11432
11550
 
11433
11551
  if (entry->fields[1].descriptortype == kUpb_FieldType_Message ||
11434
11552
  entry->fields[1].descriptortype == kUpb_FieldType_Group) {
11435
- /* Create proactively to handle the case where it doesn't appear. */
11436
- ent.data.v.val =
11437
- upb_value_ptr(_upb_Message_New(entry->subs[0].submsg, &d->arena));
11553
+ const upb_MiniTable* submsg_table = entry->subs[0].submsg;
11554
+ // Any sub-message entry must be linked. We do not allow dynamic tree
11555
+ // shaking in this case.
11556
+ UPB_ASSERT(submsg_table);
11557
+
11558
+ // Create proactively to handle the case where it doesn't appear. */
11559
+ ent.data.v.val = upb_value_ptr(_upb_Message_New(submsg_table, &d->arena));
11438
11560
  }
11439
11561
 
11440
- const char* start = ptr;
11441
11562
  ptr =
11442
11563
  _upb_Decoder_DecodeSubMessage(d, ptr, &ent.data, subs, field, val->size);
11443
11564
  // check if ent had any unknown fields
11444
11565
  size_t size;
11445
11566
  upb_Message_GetUnknown(&ent.data, &size);
11446
11567
  if (size != 0) {
11568
+ char* buf;
11569
+ size_t size;
11447
11570
  uint32_t tag = ((uint32_t)field->number << 3) | kUpb_WireType_Delimited;
11448
- _upb_Decoder_AddUnknownVarints(d, msg, tag, (uint32_t)(ptr - start));
11449
- if (!_upb_Message_AddUnknown(msg, start, ptr - start, &d->arena)) {
11571
+ upb_EncodeStatus status =
11572
+ upb_Encode(&ent.data, entry, 0, &d->arena, &buf, &size);
11573
+ if (status != kUpb_EncodeStatus_Ok) {
11574
+ _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
11575
+ }
11576
+ _upb_Decoder_AddUnknownVarints(d, msg, tag, size);
11577
+ if (!_upb_Message_AddUnknown(msg, buf, size, &d->arena)) {
11450
11578
  _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
11451
11579
  }
11452
11580
  } else {
@@ -13601,6 +13729,15 @@ static void encode_msgset_item(upb_encstate* e,
13601
13729
  encode_tag(e, kUpb_MsgSet_Item, kUpb_WireType_StartGroup);
13602
13730
  }
13603
13731
 
13732
+ static void encode_ext(upb_encstate* e, const upb_Message_Extension* ext,
13733
+ bool is_message_set) {
13734
+ if (UPB_UNLIKELY(is_message_set)) {
13735
+ encode_msgset_item(e, ext);
13736
+ } else {
13737
+ encode_field(e, &ext->data, &ext->ext->sub, &ext->ext->field);
13738
+ }
13739
+ }
13740
+
13604
13741
  static void encode_message(upb_encstate* e, const upb_Message* msg,
13605
13742
  const upb_MiniTable* m, size_t* size) {
13606
13743
  size_t pre_len = e->limit - e->ptr;
@@ -13630,12 +13767,17 @@ static void encode_message(upb_encstate* e, const upb_Message* msg,
13630
13767
  size_t ext_count;
13631
13768
  const upb_Message_Extension* ext = _upb_Message_Getexts(msg, &ext_count);
13632
13769
  if (ext_count) {
13633
- const upb_Message_Extension* end = ext + ext_count;
13634
- for (; ext != end; ext++) {
13635
- if (UPB_UNLIKELY(m->ext == kUpb_ExtMode_IsMessageSet)) {
13636
- encode_msgset_item(e, ext);
13637
- } else {
13638
- encode_field(e, &ext->data, &ext->ext->sub, &ext->ext->field);
13770
+ if (e->options & kUpb_EncodeOption_Deterministic) {
13771
+ _upb_sortedmap sorted;
13772
+ _upb_mapsorter_pushexts(&e->sorter, ext, ext_count, &sorted);
13773
+ while (_upb_sortedmap_nextext(&e->sorter, &sorted, &ext)) {
13774
+ encode_ext(e, ext, m->ext == kUpb_ExtMode_IsMessageSet);
13775
+ }
13776
+ _upb_mapsorter_popmap(&e->sorter, &sorted);
13777
+ } else {
13778
+ const upb_Message_Extension* end = ext + ext_count;
13779
+ for (; ext != end; ext++) {
13780
+ encode_ext(e, ext, m->ext == kUpb_ExtMode_IsMessageSet);
13639
13781
  }
13640
13782
  }
13641
13783
  }