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

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.

@@ -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
  }