google-protobuf 3.17.3-x64-mingw32 → 3.18.0.rc.1-x64-mingw32

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.

@@ -17,5 +17,4 @@ end
17
17
  $objs = ["protobuf.o", "convert.o", "defs.o", "message.o",
18
18
  "repeated_field.o", "map.o", "ruby-upb.o", "wrap_memcpy.o"]
19
19
 
20
- find_header('third_party/wyhash/wyhash.h', '../../../..')
21
20
  create_makefile("google/protobuf_c")
@@ -35,7 +35,6 @@
35
35
  #include "map.h"
36
36
  #include "protobuf.h"
37
37
  #include "repeated_field.h"
38
- #include "third_party/wyhash/wyhash.h"
39
38
 
40
39
  static VALUE cParseError = Qnil;
41
40
  static ID descriptor_instancevar_interned;
@@ -717,7 +716,7 @@ uint64_t Message_Hash(const upb_msg* msg, const upb_msgdef* m, uint64_t seed) {
717
716
  &size);
718
717
 
719
718
  if (data) {
720
- uint64_t ret = wyhash(data, size, seed, _wyp);
719
+ uint64_t ret = Wyhash(data, size, seed, kWyhashSalt);
721
720
  upb_arena_free(arena);
722
721
  return ret;
723
722
  } else {
@@ -34,7 +34,6 @@
34
34
  #include "defs.h"
35
35
  #include "message.h"
36
36
  #include "protobuf.h"
37
- #include "third_party/wyhash/wyhash.h"
38
37
 
39
38
  // -----------------------------------------------------------------------------
40
39
  // Repeated field container type.
@@ -524,24 +524,43 @@ static void decode_munge(int type, wireval *val) {
524
524
  }
525
525
 
526
526
  static const upb_msglayout_field *upb_find_field(const upb_msglayout *l,
527
- uint32_t field_number) {
527
+ uint32_t field_number,
528
+ int *last_field_index) {
528
529
  static upb_msglayout_field none = {0, 0, 0, 0, 0, 0};
529
530
 
530
- /* Lots of optimization opportunities here. */
531
- int i;
532
531
  if (l == NULL) return &none;
533
- for (i = 0; i < l->field_count; i++) {
534
- if (l->fields[i].number == field_number) {
535
- return &l->fields[i];
532
+
533
+ size_t idx = ((size_t)field_number) - 1; // 0 wraps to SIZE_MAX
534
+ if (idx < l->dense_below) {
535
+ goto found;
536
+ }
537
+
538
+ /* Resume scanning from last_field_index since fields are usually in order. */
539
+ int last = *last_field_index;
540
+ for (idx = last; idx < l->field_count; idx++) {
541
+ if (l->fields[idx].number == field_number) {
542
+ goto found;
543
+ }
544
+ }
545
+
546
+ for (idx = 0; idx < last; idx++) {
547
+ if (l->fields[idx].number == field_number) {
548
+ goto found;
536
549
  }
537
550
  }
538
551
 
539
552
  return &none; /* Unknown field. */
553
+
554
+ found:
555
+ UPB_ASSERT(l->fields[idx].number == field_number);
556
+ *last_field_index = idx;
557
+ return &l->fields[idx];
540
558
  }
541
559
 
542
- static upb_msg *decode_newsubmsg(upb_decstate *d, const upb_msglayout *layout,
560
+ static upb_msg *decode_newsubmsg(upb_decstate *d,
561
+ upb_msglayout const *const *submsgs,
543
562
  const upb_msglayout_field *field) {
544
- const upb_msglayout *subl = layout->submsgs[field->submsg_index];
563
+ const upb_msglayout *subl = submsgs[field->submsg_index];
545
564
  return _upb_msg_new_inl(subl, &d->arena);
546
565
  }
547
566
 
@@ -571,9 +590,10 @@ static const char *decode_readstr(upb_decstate *d, const char *ptr, int size,
571
590
 
572
591
  UPB_FORCEINLINE
573
592
  static const char *decode_tosubmsg(upb_decstate *d, const char *ptr,
574
- upb_msg *submsg, const upb_msglayout *layout,
593
+ upb_msg *submsg,
594
+ upb_msglayout const *const *submsgs,
575
595
  const upb_msglayout_field *field, int size) {
576
- const upb_msglayout *subl = layout->submsgs[field->submsg_index];
596
+ const upb_msglayout *subl = submsgs[field->submsg_index];
577
597
  int saved_delta = decode_pushlimit(d, ptr, size);
578
598
  if (--d->depth < 0) decode_err(d);
579
599
  if (!decode_isdone(d, &ptr)) {
@@ -602,15 +622,17 @@ static const char *decode_group(upb_decstate *d, const char *ptr,
602
622
 
603
623
  UPB_FORCEINLINE
604
624
  static const char *decode_togroup(upb_decstate *d, const char *ptr,
605
- upb_msg *submsg, const upb_msglayout *layout,
625
+ upb_msg *submsg,
626
+ upb_msglayout const *const *submsgs,
606
627
  const upb_msglayout_field *field) {
607
- const upb_msglayout *subl = layout->submsgs[field->submsg_index];
628
+ const upb_msglayout *subl = submsgs[field->submsg_index];
608
629
  return decode_group(d, ptr, submsg, subl, field->number);
609
630
  }
610
631
 
611
632
  static const char *decode_toarray(upb_decstate *d, const char *ptr,
612
- upb_msg *msg, const upb_msglayout *layout,
613
- const upb_msglayout_field *field, wireval val,
633
+ upb_msg *msg,
634
+ upb_msglayout const *const *submsgs,
635
+ const upb_msglayout_field *field, wireval *val,
614
636
  int op) {
615
637
  upb_array **arrp = UPB_PTR_AT(msg, field->offset, void);
616
638
  upb_array *arr = *arrp;
@@ -632,27 +654,27 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
632
654
  /* Append scalar value. */
633
655
  mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << op, void);
634
656
  arr->len++;
635
- memcpy(mem, &val, 1 << op);
657
+ memcpy(mem, val, 1 << op);
636
658
  return ptr;
637
659
  case OP_STRING:
638
- decode_verifyutf8(d, ptr, val.size);
660
+ decode_verifyutf8(d, ptr, val->size);
639
661
  /* Fallthrough. */
640
662
  case OP_BYTES: {
641
663
  /* Append bytes. */
642
664
  upb_strview *str = (upb_strview*)_upb_array_ptr(arr) + arr->len;
643
665
  arr->len++;
644
- return decode_readstr(d, ptr, val.size, str);
666
+ return decode_readstr(d, ptr, val->size, str);
645
667
  }
646
668
  case OP_SUBMSG: {
647
669
  /* Append submessage / group. */
648
- upb_msg *submsg = decode_newsubmsg(d, layout, field);
670
+ upb_msg *submsg = decode_newsubmsg(d, submsgs, field);
649
671
  *UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(void *), upb_msg *) =
650
672
  submsg;
651
673
  arr->len++;
652
674
  if (UPB_UNLIKELY(field->descriptortype == UPB_DTYPE_GROUP)) {
653
- return decode_togroup(d, ptr, submsg, layout, field);
675
+ return decode_togroup(d, ptr, submsg, submsgs, field);
654
676
  } else {
655
- return decode_tosubmsg(d, ptr, submsg, layout, field, val.size);
677
+ return decode_tosubmsg(d, ptr, submsg, submsgs, field, val->size);
656
678
  }
657
679
  }
658
680
  case OP_FIXPCK_LG2(2):
@@ -660,15 +682,15 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
660
682
  /* Fixed packed. */
661
683
  int lg2 = op - OP_FIXPCK_LG2(0);
662
684
  int mask = (1 << lg2) - 1;
663
- size_t count = val.size >> lg2;
664
- if ((val.size & mask) != 0) {
685
+ size_t count = val->size >> lg2;
686
+ if ((val->size & mask) != 0) {
665
687
  decode_err(d); /* Length isn't a round multiple of elem size. */
666
688
  }
667
689
  decode_reserve(d, arr, count);
668
690
  mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
669
691
  arr->len += count;
670
- memcpy(mem, ptr, val.size); /* XXX: ptr boundary. */
671
- return ptr + val.size;
692
+ memcpy(mem, ptr, val->size); /* XXX: ptr boundary. */
693
+ return ptr + val->size;
672
694
  }
673
695
  case OP_VARPCK_LG2(0):
674
696
  case OP_VARPCK_LG2(2):
@@ -676,7 +698,7 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
676
698
  /* Varint packed. */
677
699
  int lg2 = op - OP_VARPCK_LG2(0);
678
700
  int scale = 1 << lg2;
679
- int saved_limit = decode_pushlimit(d, ptr, val.size);
701
+ int saved_limit = decode_pushlimit(d, ptr, val->size);
680
702
  char *out = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void);
681
703
  while (!decode_isdone(d, &ptr)) {
682
704
  wireval elem;
@@ -698,16 +720,15 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
698
720
  }
699
721
 
700
722
  static const char *decode_tomap(upb_decstate *d, const char *ptr, upb_msg *msg,
701
- const upb_msglayout *layout,
702
- const upb_msglayout_field *field, wireval val) {
723
+ upb_msglayout const *const *submsgs,
724
+ const upb_msglayout_field *field, wireval *val) {
703
725
  upb_map **map_p = UPB_PTR_AT(msg, field->offset, upb_map *);
704
726
  upb_map *map = *map_p;
705
727
  upb_map_entry ent;
706
- const upb_msglayout *entry = layout->submsgs[field->submsg_index];
728
+ const upb_msglayout *entry = submsgs[field->submsg_index];
707
729
 
708
730
  if (!map) {
709
731
  /* Lazily create map. */
710
- const upb_msglayout *entry = layout->submsgs[field->submsg_index];
711
732
  const upb_msglayout_field *key_field = &entry->fields[0];
712
733
  const upb_msglayout_field *val_field = &entry->fields[1];
713
734
  char key_size = desctype_to_mapsize[key_field->descriptortype];
@@ -727,28 +748,28 @@ static const char *decode_tomap(upb_decstate *d, const char *ptr, upb_msg *msg,
727
748
  ent.v.val = upb_value_ptr(_upb_msg_new(entry->submsgs[0], &d->arena));
728
749
  }
729
750
 
730
- ptr = decode_tosubmsg(d, ptr, &ent.k, layout, field, val.size);
751
+ ptr = decode_tosubmsg(d, ptr, &ent.k, submsgs, field, val->size);
731
752
  _upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, &d->arena);
732
753
  return ptr;
733
754
  }
734
755
 
735
756
  static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg,
736
- const upb_msglayout *layout,
737
- const upb_msglayout_field *field, wireval val,
757
+ upb_msglayout const *const *submsgs,
758
+ const upb_msglayout_field *field, wireval *val,
738
759
  int op) {
739
760
  void *mem = UPB_PTR_AT(msg, field->offset, void);
740
761
  int type = field->descriptortype;
741
762
 
742
763
  /* Set presence if necessary. */
743
- if (field->presence < 0) {
764
+ if (field->presence > 0) {
765
+ _upb_sethas_field(msg, field);
766
+ } else if (field->presence < 0) {
744
767
  /* Oneof case */
745
768
  uint32_t *oneof_case = _upb_oneofcase_field(msg, field);
746
769
  if (op == OP_SUBMSG && *oneof_case != field->number) {
747
770
  memset(mem, 0, sizeof(void*));
748
771
  }
749
772
  *oneof_case = field->number;
750
- } else if (field->presence > 0) {
751
- _upb_sethas_field(msg, field);
752
773
  }
753
774
 
754
775
  /* Store into message. */
@@ -757,29 +778,29 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg,
757
778
  upb_msg **submsgp = mem;
758
779
  upb_msg *submsg = *submsgp;
759
780
  if (!submsg) {
760
- submsg = decode_newsubmsg(d, layout, field);
781
+ submsg = decode_newsubmsg(d, submsgs, field);
761
782
  *submsgp = submsg;
762
783
  }
763
784
  if (UPB_UNLIKELY(type == UPB_DTYPE_GROUP)) {
764
- ptr = decode_togroup(d, ptr, submsg, layout, field);
785
+ ptr = decode_togroup(d, ptr, submsg, submsgs, field);
765
786
  } else {
766
- ptr = decode_tosubmsg(d, ptr, submsg, layout, field, val.size);
787
+ ptr = decode_tosubmsg(d, ptr, submsg, submsgs, field, val->size);
767
788
  }
768
789
  break;
769
790
  }
770
791
  case OP_STRING:
771
- decode_verifyutf8(d, ptr, val.size);
792
+ decode_verifyutf8(d, ptr, val->size);
772
793
  /* Fallthrough. */
773
794
  case OP_BYTES:
774
- return decode_readstr(d, ptr, val.size, mem);
795
+ return decode_readstr(d, ptr, val->size, mem);
775
796
  case OP_SCALAR_LG2(3):
776
- memcpy(mem, &val, 8);
797
+ memcpy(mem, val, 8);
777
798
  break;
778
799
  case OP_SCALAR_LG2(2):
779
- memcpy(mem, &val, 4);
800
+ memcpy(mem, val, 4);
780
801
  break;
781
802
  case OP_SCALAR_LG2(0):
782
- memcpy(mem, &val, 1);
803
+ memcpy(mem, val, 1);
783
804
  break;
784
805
  default:
785
806
  UPB_UNREACHABLE();
@@ -805,6 +826,7 @@ static bool decode_tryfastdispatch(upb_decstate *d, const char **ptr,
805
826
  UPB_NOINLINE
806
827
  static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
807
828
  const upb_msglayout *layout) {
829
+ int last_field_index = 0;
808
830
  while (true) {
809
831
  uint32_t tag;
810
832
  const upb_msglayout_field *field;
@@ -819,7 +841,7 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
819
841
  field_number = tag >> 3;
820
842
  wire_type = tag & 7;
821
843
 
822
- field = upb_find_field(layout, field_number);
844
+ field = upb_find_field(layout, field_number, &last_field_index);
823
845
 
824
846
  switch (wire_type) {
825
847
  case UPB_WIRE_TYPE_VARINT:
@@ -844,7 +866,7 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
844
866
  case UPB_WIRE_TYPE_DELIMITED: {
845
867
  int ndx = field->descriptortype;
846
868
  uint64_t size;
847
- if (_upb_isrepeated(field)) ndx += 18;
869
+ if (_upb_getmode(field) == _UPB_MODE_ARRAY) ndx += 18;
848
870
  ptr = decode_varint64(d, ptr, &size);
849
871
  if (size >= INT32_MAX ||
850
872
  ptr - d->end + (int32_t)size > d->limit) {
@@ -868,17 +890,18 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
868
890
 
869
891
  if (op >= 0) {
870
892
  /* Parse, using op for dispatch. */
871
- switch (field->label) {
872
- case UPB_LABEL_REPEATED:
873
- case _UPB_LABEL_PACKED:
874
- ptr = decode_toarray(d, ptr, msg, layout, field, val, op);
893
+ switch (_upb_getmode(field)) {
894
+ case _UPB_MODE_ARRAY:
895
+ ptr = decode_toarray(d, ptr, msg, layout->submsgs, field, &val, op);
875
896
  break;
876
- case _UPB_LABEL_MAP:
877
- ptr = decode_tomap(d, ptr, msg, layout, field, val);
897
+ case _UPB_MODE_MAP:
898
+ ptr = decode_tomap(d, ptr, msg, layout->submsgs, field, &val);
878
899
  break;
879
- default:
880
- ptr = decode_tomsg(d, ptr, msg, layout, field, val, op);
900
+ case _UPB_MODE_SCALAR:
901
+ ptr = decode_tomsg(d, ptr, msg, layout->submsgs, field, &val, op);
881
902
  break;
903
+ default:
904
+ UPB_UNREACHABLE();
882
905
  }
883
906
  } else {
884
907
  unknown:
@@ -924,7 +947,8 @@ static bool decode_top(struct upb_decstate *d, const char *buf, void *msg,
924
947
  }
925
948
 
926
949
  bool _upb_decode(const char *buf, size_t size, void *msg,
927
- const upb_msglayout *l, upb_arena *arena, int options) {
950
+ const upb_msglayout *l, const upb_extreg *extreg, int options,
951
+ upb_arena *arena) {
928
952
  bool ok;
929
953
  upb_decstate state;
930
954
  unsigned depth = (unsigned)options >> 16;
@@ -1126,7 +1150,7 @@ static void encode_fixedarray(upb_encstate *e, const upb_array *arr,
1126
1150
  }
1127
1151
  }
1128
1152
 
1129
- static void encode_message(upb_encstate *e, const char *msg,
1153
+ static void encode_message(upb_encstate *e, const upb_msg *msg,
1130
1154
  const upb_msglayout *m, size_t *size);
1131
1155
 
1132
1156
  static void encode_scalar(upb_encstate *e, const void *_field_mem,
@@ -1218,10 +1242,10 @@ static void encode_scalar(upb_encstate *e, const void *_field_mem,
1218
1242
  encode_tag(e, f->number, wire_type);
1219
1243
  }
1220
1244
 
1221
- static void encode_array(upb_encstate *e, const char *field_mem,
1245
+ static void encode_array(upb_encstate *e, const upb_msg *msg,
1222
1246
  const upb_msglayout *m, const upb_msglayout_field *f) {
1223
- const upb_array *arr = *(const upb_array**)field_mem;
1224
- bool packed = f->label == _UPB_LABEL_PACKED;
1247
+ const upb_array *arr = *UPB_PTR_AT(msg, f->offset, upb_array*);
1248
+ bool packed = f->mode & _UPB_MODE_IS_PACKED;
1225
1249
  size_t pre_len = e->limit - e->ptr;
1226
1250
 
1227
1251
  if (arr == NULL || arr->len == 0) {
@@ -1337,9 +1361,9 @@ static void encode_mapentry(upb_encstate *e, uint32_t number,
1337
1361
  encode_tag(e, number, UPB_WIRE_TYPE_DELIMITED);
1338
1362
  }
1339
1363
 
1340
- static void encode_map(upb_encstate *e, const char *field_mem,
1364
+ static void encode_map(upb_encstate *e, const upb_msg *msg,
1341
1365
  const upb_msglayout *m, const upb_msglayout_field *f) {
1342
- const upb_map *map = *(const upb_map**)field_mem;
1366
+ const upb_map *map = *UPB_PTR_AT(msg, f->offset, const upb_map*);
1343
1367
  const upb_msglayout *layout = m->submsgs[f->submsg_index];
1344
1368
  UPB_ASSERT(layout->field_count == 2);
1345
1369
 
@@ -1385,7 +1409,7 @@ static void encode_scalarfield(upb_encstate *e, const char *msg,
1385
1409
  encode_scalar(e, msg + f->offset, m, f, skip_empty);
1386
1410
  }
1387
1411
 
1388
- static void encode_message(upb_encstate *e, const char *msg,
1412
+ static void encode_message(upb_encstate *e, const upb_msg *msg,
1389
1413
  const upb_msglayout *m, size_t *size) {
1390
1414
  size_t pre_len = e->limit - e->ptr;
1391
1415
  const upb_msglayout_field *f = &m->fields[m->field_count];
@@ -1402,12 +1426,18 @@ static void encode_message(upb_encstate *e, const char *msg,
1402
1426
 
1403
1427
  while (f != first) {
1404
1428
  f--;
1405
- if (_upb_isrepeated(f)) {
1406
- encode_array(e, msg + f->offset, m, f);
1407
- } else if (f->label == _UPB_LABEL_MAP) {
1408
- encode_map(e, msg + f->offset, m, f);
1409
- } else {
1410
- encode_scalarfield(e, msg, m, f);
1429
+ switch (_upb_getmode(f)) {
1430
+ case _UPB_MODE_ARRAY:
1431
+ encode_array(e, msg, m, f);
1432
+ break;
1433
+ case _UPB_MODE_MAP:
1434
+ encode_map(e, msg, m, f);
1435
+ break;
1436
+ case _UPB_MODE_SCALAR:
1437
+ encode_scalarfield(e, msg, m, f);
1438
+ break;
1439
+ default:
1440
+ UPB_UNREACHABLE();
1411
1441
  }
1412
1442
  }
1413
1443
 
@@ -1452,7 +1482,7 @@ char *upb_encode_ex(const void *msg, const upb_msglayout *l, int options,
1452
1482
 
1453
1483
  /** upb_msg *******************************************************************/
1454
1484
 
1455
- static const size_t overhead = sizeof(upb_msg_internal);
1485
+ static const size_t overhead = sizeof(upb_msg_internaldata);
1456
1486
 
1457
1487
  static const upb_msg_internal *upb_msg_getinternal_const(const upb_msg *msg) {
1458
1488
  ptrdiff_t size = sizeof(upb_msg_internal);
@@ -1468,49 +1498,107 @@ void _upb_msg_clear(upb_msg *msg, const upb_msglayout *l) {
1468
1498
  memset(mem, 0, upb_msg_sizeof(l));
1469
1499
  }
1470
1500
 
1501
+ static bool realloc_internal(upb_msg *msg, size_t need, upb_arena *arena) {
1502
+ upb_msg_internal *in = upb_msg_getinternal(msg);
1503
+ if (!in->internal) {
1504
+ /* No internal data, allocate from scratch. */
1505
+ size_t size = UPB_MAX(128, _upb_lg2ceilsize(need + overhead));
1506
+ upb_msg_internaldata *internal = upb_arena_malloc(arena, size);
1507
+ if (!internal) return false;
1508
+ internal->size = size;
1509
+ internal->unknown_end = overhead;
1510
+ internal->ext_begin = size;
1511
+ in->internal = internal;
1512
+ } else if (in->internal->ext_begin - in->internal->unknown_end < need) {
1513
+ /* Internal data is too small, reallocate. */
1514
+ size_t new_size = _upb_lg2ceilsize(in->internal->size + need);
1515
+ size_t ext_bytes = in->internal->size - in->internal->ext_begin;
1516
+ size_t new_ext_begin = new_size - ext_bytes;
1517
+ upb_msg_internaldata *internal =
1518
+ upb_arena_realloc(arena, in->internal, in->internal->size, new_size);
1519
+ if (!internal) return false;
1520
+ if (ext_bytes) {
1521
+ /* Need to move extension data to the end. */
1522
+ char *ptr = (char*)internal;
1523
+ memmove(ptr + new_ext_begin, ptr + internal->ext_begin, ext_bytes);
1524
+ }
1525
+ internal->ext_begin = new_ext_begin;
1526
+ internal->size = new_size;
1527
+ in->internal = internal;
1528
+ }
1529
+ UPB_ASSERT(in->internal->ext_begin - in->internal->unknown_end >= need);
1530
+ return true;
1531
+ }
1532
+
1471
1533
  bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len,
1472
1534
  upb_arena *arena) {
1473
-
1535
+ if (!realloc_internal(msg, len, arena)) return false;
1474
1536
  upb_msg_internal *in = upb_msg_getinternal(msg);
1475
- if (!in->unknown) {
1476
- size_t size = 128;
1477
- while (size < len) size *= 2;
1478
- in->unknown = upb_arena_malloc(arena, size + overhead);
1479
- if (!in->unknown) return false;
1480
- in->unknown->size = size;
1481
- in->unknown->len = 0;
1482
- } else if (in->unknown->size - in->unknown->len < len) {
1483
- size_t need = in->unknown->len + len;
1484
- size_t size = in->unknown->size;
1485
- while (size < need) size *= 2;
1486
- in->unknown = upb_arena_realloc(
1487
- arena, in->unknown, in->unknown->size + overhead, size + overhead);
1488
- if (!in->unknown) return false;
1489
- in->unknown->size = size;
1490
- }
1491
- memcpy(UPB_PTR_AT(in->unknown + 1, in->unknown->len, char), data, len);
1492
- in->unknown->len += len;
1537
+ memcpy(UPB_PTR_AT(in->internal, in->internal->unknown_end, char), data, len);
1538
+ in->internal->unknown_end += len;
1493
1539
  return true;
1494
1540
  }
1495
1541
 
1496
1542
  void _upb_msg_discardunknown_shallow(upb_msg *msg) {
1497
1543
  upb_msg_internal *in = upb_msg_getinternal(msg);
1498
- if (in->unknown) {
1499
- in->unknown->len = 0;
1544
+ if (in->internal) {
1545
+ in->internal->unknown_end = overhead;
1500
1546
  }
1501
1547
  }
1502
1548
 
1503
1549
  const char *upb_msg_getunknown(const upb_msg *msg, size_t *len) {
1504
1550
  const upb_msg_internal *in = upb_msg_getinternal_const(msg);
1505
- if (in->unknown) {
1506
- *len = in->unknown->len;
1507
- return (char*)(in->unknown + 1);
1551
+ if (in->internal) {
1552
+ *len = in->internal->unknown_end - overhead;
1553
+ return (char*)(in->internal + 1);
1508
1554
  } else {
1509
1555
  *len = 0;
1510
1556
  return NULL;
1511
1557
  }
1512
1558
  }
1513
1559
 
1560
+ const upb_msg_ext *_upb_msg_getexts(const upb_msg *msg, size_t *count) {
1561
+ const upb_msg_internal *in = upb_msg_getinternal_const(msg);
1562
+ if (in->internal) {
1563
+ *count =
1564
+ (in->internal->size - in->internal->ext_begin) / sizeof(upb_msg_ext);
1565
+ return UPB_PTR_AT(in->internal, in->internal->ext_begin, void);
1566
+ } else {
1567
+ *count = 0;
1568
+ return NULL;
1569
+ }
1570
+ }
1571
+
1572
+ const upb_msg_ext *_upb_msg_getext(const upb_msg *msg,
1573
+ const upb_msglayout_ext *e) {
1574
+ size_t n;
1575
+ const upb_msg_ext *ext = _upb_msg_getexts(msg, &n);
1576
+
1577
+ /* For now we use linear search exclusively to find extensions. If this
1578
+ * becomes an issue due to messages with lots of extensions, we can introduce
1579
+ * a table of some sort. */
1580
+ for (size_t i = 0; i < n; i++) {
1581
+ if (ext[i].ext == e) {
1582
+ return &ext[i];
1583
+ }
1584
+ }
1585
+
1586
+ return NULL;
1587
+ }
1588
+
1589
+ upb_msg_ext *_upb_msg_getorcreateext(upb_msg *msg, const upb_msglayout_ext *e,
1590
+ upb_arena *arena) {
1591
+ upb_msg_ext *ext = (upb_msg_ext*)_upb_msg_getext(msg, e);
1592
+ if (ext) return ext;
1593
+ if (!realloc_internal(msg, sizeof(upb_msg_ext), arena)) return NULL;
1594
+ upb_msg_internal *in = upb_msg_getinternal(msg);
1595
+ in->internal->ext_begin -= sizeof(upb_msg_ext);
1596
+ ext = UPB_PTR_AT(in->internal, in->internal->ext_begin, void);
1597
+ memset(ext, 0, sizeof(upb_msg_ext));
1598
+ ext->ext = e;
1599
+ return ext;
1600
+ }
1601
+
1514
1602
  /** upb_array *****************************************************************/
1515
1603
 
1516
1604
  bool _upb_array_realloc(upb_array *arr, size_t min_size, upb_arena *arena) {
@@ -1700,6 +1788,63 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type,
1700
1788
  return true;
1701
1789
  }
1702
1790
 
1791
+ /** upb_extreg ****************************************************************/
1792
+
1793
+ struct upb_extreg {
1794
+ upb_arena *arena;
1795
+ upb_strtable exts; /* Key is upb_msglayout* concatenated with fieldnum. */
1796
+ };
1797
+
1798
+ #define EXTREG_KEY_SIZE (sizeof(upb_msglayout*) + sizeof(uint32_t))
1799
+
1800
+ static void extreg_key(char *buf, const upb_msglayout *l, uint32_t fieldnum) {
1801
+ memcpy(buf, &l, sizeof(l));
1802
+ memcpy(buf + sizeof(l), &fieldnum, sizeof(fieldnum));
1803
+ }
1804
+
1805
+ upb_extreg *upb_extreg_new(upb_arena *arena) {
1806
+ upb_extreg *r = upb_arena_malloc(arena, sizeof(*r));
1807
+ if (!r) return NULL;
1808
+ r->arena = arena;
1809
+ if (!upb_strtable_init(&r->exts, 8, arena)) return NULL;
1810
+ return r;
1811
+ }
1812
+
1813
+ bool _upb_extreg_add(upb_extreg *r, const upb_msglayout_ext *e, size_t count) {
1814
+ char buf[EXTREG_KEY_SIZE];
1815
+ const upb_msglayout_ext *start = e;
1816
+ const upb_msglayout_ext *end = e + count;
1817
+ for (; e < end; e++) {
1818
+ extreg_key(buf, e->extendee, e->field.number);
1819
+ if (!upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE,
1820
+ upb_value_constptr(e), r->arena)) {
1821
+ goto failure;
1822
+ }
1823
+ }
1824
+ return true;
1825
+
1826
+ failure:
1827
+ /* Back out the entries previously added. */
1828
+ for (end = e, e = start; e < end; e++) {
1829
+ extreg_key(buf, e->extendee, e->field.number);
1830
+ upb_strtable_remove(&r->exts, buf, EXTREG_KEY_SIZE, NULL);
1831
+ }
1832
+ return false;
1833
+ }
1834
+
1835
+ const upb_msglayout_field *_upb_extreg_get(const upb_extreg *r,
1836
+ const upb_msglayout *l,
1837
+ uint32_t num) {
1838
+ char buf[EXTREG_KEY_SIZE];
1839
+ upb_value v;
1840
+ extreg_key(buf, l, num);
1841
+ if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, &v)) {
1842
+ return upb_value_getconstptr(v);
1843
+ } else {
1844
+ return NULL;
1845
+ }
1846
+ }
1847
+
1703
1848
  /** upb/table.c ************************************************************/
1704
1849
  /*
1705
1850
  * upb_table Implementation
@@ -1709,7 +1854,6 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type,
1709
1854
 
1710
1855
  #include <string.h>
1711
1856
 
1712
- #include "third_party/wyhash/wyhash.h"
1713
1857
 
1714
1858
  /* Must be last. */
1715
1859
 
@@ -1982,8 +2126,143 @@ static upb_tabkey strcopy(lookupkey_t k2, upb_arena *a) {
1982
2126
  return (uintptr_t)str;
1983
2127
  }
1984
2128
 
2129
+ /* Adapted from ABSL's wyhash. */
2130
+
2131
+ static uint64_t UnalignedLoad64(const void *p) {
2132
+ uint64_t val;
2133
+ memcpy(&val, p, 8);
2134
+ return val;
2135
+ }
2136
+
2137
+ static uint32_t UnalignedLoad32(const void *p) {
2138
+ uint32_t val;
2139
+ memcpy(&val, p, 4);
2140
+ return val;
2141
+ }
2142
+
2143
+ #if defined(_MSC_VER) && defined(_M_X64)
2144
+ #include <intrin.h>
2145
+ #endif
2146
+
2147
+ /* Computes a * b, returning the low 64 bits of the result and storing the high
2148
+ * 64 bits in |*high|. */
2149
+ static uint64_t upb_umul128(uint64_t v0, uint64_t v1, uint64_t* out_high) {
2150
+ #ifdef __SIZEOF_INT128__
2151
+ __uint128_t p = v0;
2152
+ p *= v1;
2153
+ *out_high = (uint64_t)(p >> 64);
2154
+ return (uint64_t)p;
2155
+ #elif defined(_MSC_VER) && defined(_M_X64)
2156
+ return _umul128(v0, v1, out_high);
2157
+ #else
2158
+ uint64_t a32 = v0 >> 32;
2159
+ uint64_t a00 = v0 & 0xffffffff;
2160
+ uint64_t b32 = v1 >> 32;
2161
+ uint64_t b00 = v1 & 0xffffffff;
2162
+ uint64_t high = a32 * b32;
2163
+ uint64_t low = a00 * b00;
2164
+ uint64_t mid1 = a32 * b00;
2165
+ uint64_t mid2 = a00 * b32;
2166
+ low += (mid1 << 32) + (mid2 << 32);
2167
+ // Omit carry bit, for mixing we do not care about exact numerical precision.
2168
+ high += (mid1 >> 32) + (mid2 >> 32);
2169
+ *out_high = high;
2170
+ return low;
2171
+ #endif
2172
+ }
2173
+
2174
+ static uint64_t WyhashMix(uint64_t v0, uint64_t v1) {
2175
+ uint64_t high;
2176
+ uint64_t low = upb_umul128(v0, v1, &high);
2177
+ return low ^ high;
2178
+ }
2179
+
2180
+ uint64_t Wyhash(const void *data, size_t len, uint64_t seed,
2181
+ const uint64_t salt[]) {
2182
+ const uint8_t* ptr = (const uint8_t*)data;
2183
+ uint64_t starting_length = (uint64_t)len;
2184
+ uint64_t current_state = seed ^ salt[0];
2185
+
2186
+ if (len > 64) {
2187
+ // If we have more than 64 bytes, we're going to handle chunks of 64
2188
+ // bytes at a time. We're going to build up two separate hash states
2189
+ // which we will then hash together.
2190
+ uint64_t duplicated_state = current_state;
2191
+
2192
+ do {
2193
+ uint64_t a = UnalignedLoad64(ptr);
2194
+ uint64_t b = UnalignedLoad64(ptr + 8);
2195
+ uint64_t c = UnalignedLoad64(ptr + 16);
2196
+ uint64_t d = UnalignedLoad64(ptr + 24);
2197
+ uint64_t e = UnalignedLoad64(ptr + 32);
2198
+ uint64_t f = UnalignedLoad64(ptr + 40);
2199
+ uint64_t g = UnalignedLoad64(ptr + 48);
2200
+ uint64_t h = UnalignedLoad64(ptr + 56);
2201
+
2202
+ uint64_t cs0 = WyhashMix(a ^ salt[1], b ^ current_state);
2203
+ uint64_t cs1 = WyhashMix(c ^ salt[2], d ^ current_state);
2204
+ current_state = (cs0 ^ cs1);
2205
+
2206
+ uint64_t ds0 = WyhashMix(e ^ salt[3], f ^ duplicated_state);
2207
+ uint64_t ds1 = WyhashMix(g ^ salt[4], h ^ duplicated_state);
2208
+ duplicated_state = (ds0 ^ ds1);
2209
+
2210
+ ptr += 64;
2211
+ len -= 64;
2212
+ } while (len > 64);
2213
+
2214
+ current_state = current_state ^ duplicated_state;
2215
+ }
2216
+
2217
+ // We now have a data `ptr` with at most 64 bytes and the current state
2218
+ // of the hashing state machine stored in current_state.
2219
+ while (len > 16) {
2220
+ uint64_t a = UnalignedLoad64(ptr);
2221
+ uint64_t b = UnalignedLoad64(ptr + 8);
2222
+
2223
+ current_state = WyhashMix(a ^ salt[1], b ^ current_state);
2224
+
2225
+ ptr += 16;
2226
+ len -= 16;
2227
+ }
2228
+
2229
+ // We now have a data `ptr` with at most 16 bytes.
2230
+ uint64_t a = 0;
2231
+ uint64_t b = 0;
2232
+ if (len > 8) {
2233
+ // When we have at least 9 and at most 16 bytes, set A to the first 64
2234
+ // bits of the input and B to the last 64 bits of the input. Yes, they will
2235
+ // overlap in the middle if we are working with less than the full 16
2236
+ // bytes.
2237
+ a = UnalignedLoad64(ptr);
2238
+ b = UnalignedLoad64(ptr + len - 8);
2239
+ } else if (len > 3) {
2240
+ // If we have at least 4 and at most 8 bytes, set A to the first 32
2241
+ // bits and B to the last 32 bits.
2242
+ a = UnalignedLoad32(ptr);
2243
+ b = UnalignedLoad32(ptr + len - 4);
2244
+ } else if (len > 0) {
2245
+ // If we have at least 1 and at most 3 bytes, read all of the provided
2246
+ // bits into A, with some adjustments.
2247
+ a = ((ptr[0] << 16) | (ptr[len >> 1] << 8) | ptr[len - 1]);
2248
+ b = 0;
2249
+ } else {
2250
+ a = 0;
2251
+ b = 0;
2252
+ }
2253
+
2254
+ uint64_t w = WyhashMix(a ^ salt[1], b ^ current_state);
2255
+ uint64_t z = salt[1] ^ starting_length;
2256
+ return WyhashMix(w, z);
2257
+ }
2258
+
2259
+ const uint64_t kWyhashSalt[5] = {
2260
+ 0x243F6A8885A308D3ULL, 0x13198A2E03707344ULL, 0xA4093822299F31D0ULL,
2261
+ 0x082EFA98EC4E6C89ULL, 0x452821E638D01377ULL,
2262
+ };
2263
+
1985
2264
  static uint32_t table_hash(const char *p, size_t n) {
1986
- return wyhash(p, n, 0, _wyp);
2265
+ return Wyhash(p, n, 0, kWyhashSalt);
1987
2266
  }
1988
2267
 
1989
2268
  static uint32_t strhash(upb_tabkey key) {
@@ -3710,13 +3989,13 @@ static const upb_msglayout *const google_protobuf_FileDescriptorSet_submsgs[1] =
3710
3989
  };
3711
3990
 
3712
3991
  static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] = {
3713
- {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
3992
+ {1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
3714
3993
  };
3715
3994
 
3716
3995
  const upb_msglayout google_protobuf_FileDescriptorSet_msginit = {
3717
3996
  &google_protobuf_FileDescriptorSet_submsgs[0],
3718
3997
  &google_protobuf_FileDescriptorSet__fields[0],
3719
- UPB_SIZE(8, 8), 1, false, 255,
3998
+ UPB_SIZE(8, 8), 1, false, 1, 255,
3720
3999
  };
3721
4000
 
3722
4001
  static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6] = {
@@ -3729,24 +4008,24 @@ static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6]
3729
4008
  };
3730
4009
 
3731
4010
  static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12] = {
3732
- {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
3733
- {2, UPB_SIZE(12, 24), 2, 0, 12, 1},
3734
- {3, UPB_SIZE(36, 72), 0, 0, 12, 3},
3735
- {4, UPB_SIZE(40, 80), 0, 0, 11, 3},
3736
- {5, UPB_SIZE(44, 88), 0, 1, 11, 3},
3737
- {6, UPB_SIZE(48, 96), 0, 4, 11, 3},
3738
- {7, UPB_SIZE(52, 104), 0, 2, 11, 3},
3739
- {8, UPB_SIZE(28, 56), 3, 3, 11, 1},
3740
- {9, UPB_SIZE(32, 64), 4, 5, 11, 1},
3741
- {10, UPB_SIZE(56, 112), 0, 0, 5, 3},
3742
- {11, UPB_SIZE(60, 120), 0, 0, 5, 3},
3743
- {12, UPB_SIZE(20, 40), 5, 0, 12, 1},
4011
+ {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4012
+ {2, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR},
4013
+ {3, UPB_SIZE(36, 72), 0, 0, 12, _UPB_MODE_ARRAY},
4014
+ {4, UPB_SIZE(40, 80), 0, 0, 11, _UPB_MODE_ARRAY},
4015
+ {5, UPB_SIZE(44, 88), 0, 1, 11, _UPB_MODE_ARRAY},
4016
+ {6, UPB_SIZE(48, 96), 0, 4, 11, _UPB_MODE_ARRAY},
4017
+ {7, UPB_SIZE(52, 104), 0, 2, 11, _UPB_MODE_ARRAY},
4018
+ {8, UPB_SIZE(28, 56), 3, 3, 11, _UPB_MODE_SCALAR},
4019
+ {9, UPB_SIZE(32, 64), 4, 5, 11, _UPB_MODE_SCALAR},
4020
+ {10, UPB_SIZE(56, 112), 0, 0, 5, _UPB_MODE_ARRAY},
4021
+ {11, UPB_SIZE(60, 120), 0, 0, 5, _UPB_MODE_ARRAY},
4022
+ {12, UPB_SIZE(20, 40), 5, 0, 12, _UPB_MODE_SCALAR},
3744
4023
  };
3745
4024
 
3746
4025
  const upb_msglayout google_protobuf_FileDescriptorProto_msginit = {
3747
4026
  &google_protobuf_FileDescriptorProto_submsgs[0],
3748
4027
  &google_protobuf_FileDescriptorProto__fields[0],
3749
- UPB_SIZE(64, 128), 12, false, 255,
4028
+ UPB_SIZE(64, 128), 12, false, 12, 255,
3750
4029
  };
3751
4030
 
3752
4031
  static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[7] = {
@@ -3760,22 +4039,22 @@ static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[7] = {
3760
4039
  };
3761
4040
 
3762
4041
  static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = {
3763
- {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
3764
- {2, UPB_SIZE(16, 32), 0, 4, 11, 3},
3765
- {3, UPB_SIZE(20, 40), 0, 0, 11, 3},
3766
- {4, UPB_SIZE(24, 48), 0, 3, 11, 3},
3767
- {5, UPB_SIZE(28, 56), 0, 1, 11, 3},
3768
- {6, UPB_SIZE(32, 64), 0, 4, 11, 3},
3769
- {7, UPB_SIZE(12, 24), 2, 5, 11, 1},
3770
- {8, UPB_SIZE(36, 72), 0, 6, 11, 3},
3771
- {9, UPB_SIZE(40, 80), 0, 2, 11, 3},
3772
- {10, UPB_SIZE(44, 88), 0, 0, 12, 3},
4042
+ {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4043
+ {2, UPB_SIZE(16, 32), 0, 4, 11, _UPB_MODE_ARRAY},
4044
+ {3, UPB_SIZE(20, 40), 0, 0, 11, _UPB_MODE_ARRAY},
4045
+ {4, UPB_SIZE(24, 48), 0, 3, 11, _UPB_MODE_ARRAY},
4046
+ {5, UPB_SIZE(28, 56), 0, 1, 11, _UPB_MODE_ARRAY},
4047
+ {6, UPB_SIZE(32, 64), 0, 4, 11, _UPB_MODE_ARRAY},
4048
+ {7, UPB_SIZE(12, 24), 2, 5, 11, _UPB_MODE_SCALAR},
4049
+ {8, UPB_SIZE(36, 72), 0, 6, 11, _UPB_MODE_ARRAY},
4050
+ {9, UPB_SIZE(40, 80), 0, 2, 11, _UPB_MODE_ARRAY},
4051
+ {10, UPB_SIZE(44, 88), 0, 0, 12, _UPB_MODE_ARRAY},
3773
4052
  };
3774
4053
 
3775
4054
  const upb_msglayout google_protobuf_DescriptorProto_msginit = {
3776
4055
  &google_protobuf_DescriptorProto_submsgs[0],
3777
4056
  &google_protobuf_DescriptorProto__fields[0],
3778
- UPB_SIZE(48, 96), 10, false, 255,
4057
+ UPB_SIZE(48, 96), 10, false, 10, 255,
3779
4058
  };
3780
4059
 
3781
4060
  static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = {
@@ -3783,26 +4062,26 @@ static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange
3783
4062
  };
3784
4063
 
3785
4064
  static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange__fields[3] = {
3786
- {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
3787
- {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
3788
- {3, UPB_SIZE(12, 16), 3, 0, 11, 1},
4065
+ {1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR},
4066
+ {2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR},
4067
+ {3, UPB_SIZE(12, 16), 3, 0, 11, _UPB_MODE_SCALAR},
3789
4068
  };
3790
4069
 
3791
4070
  const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = {
3792
4071
  &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0],
3793
4072
  &google_protobuf_DescriptorProto_ExtensionRange__fields[0],
3794
- UPB_SIZE(16, 24), 3, false, 255,
4073
+ UPB_SIZE(16, 24), 3, false, 3, 255,
3795
4074
  };
3796
4075
 
3797
4076
  static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2] = {
3798
- {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
3799
- {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
4077
+ {1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR},
4078
+ {2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR},
3800
4079
  };
3801
4080
 
3802
4081
  const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = {
3803
4082
  NULL,
3804
4083
  &google_protobuf_DescriptorProto_ReservedRange__fields[0],
3805
- UPB_SIZE(16, 16), 2, false, 255,
4084
+ UPB_SIZE(16, 16), 2, false, 2, 255,
3806
4085
  };
3807
4086
 
3808
4087
  static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1] = {
@@ -3810,13 +4089,13 @@ static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[
3810
4089
  };
3811
4090
 
3812
4091
  static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1] = {
3813
- {999, UPB_SIZE(0, 0), 0, 0, 11, 3},
4092
+ {999, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
3814
4093
  };
3815
4094
 
3816
4095
  const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = {
3817
4096
  &google_protobuf_ExtensionRangeOptions_submsgs[0],
3818
4097
  &google_protobuf_ExtensionRangeOptions__fields[0],
3819
- UPB_SIZE(8, 8), 1, false, 255,
4098
+ UPB_SIZE(8, 8), 1, false, 0, 255,
3820
4099
  };
3821
4100
 
3822
4101
  static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1] = {
@@ -3824,23 +4103,23 @@ static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1
3824
4103
  };
3825
4104
 
3826
4105
  static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11] = {
3827
- {1, UPB_SIZE(24, 24), 1, 0, 12, 1},
3828
- {2, UPB_SIZE(32, 40), 2, 0, 12, 1},
3829
- {3, UPB_SIZE(12, 12), 3, 0, 5, 1},
3830
- {4, UPB_SIZE(4, 4), 4, 0, 14, 1},
3831
- {5, UPB_SIZE(8, 8), 5, 0, 14, 1},
3832
- {6, UPB_SIZE(40, 56), 6, 0, 12, 1},
3833
- {7, UPB_SIZE(48, 72), 7, 0, 12, 1},
3834
- {8, UPB_SIZE(64, 104), 8, 0, 11, 1},
3835
- {9, UPB_SIZE(16, 16), 9, 0, 5, 1},
3836
- {10, UPB_SIZE(56, 88), 10, 0, 12, 1},
3837
- {17, UPB_SIZE(20, 20), 11, 0, 8, 1},
4106
+ {1, UPB_SIZE(24, 24), 1, 0, 12, _UPB_MODE_SCALAR},
4107
+ {2, UPB_SIZE(32, 40), 2, 0, 12, _UPB_MODE_SCALAR},
4108
+ {3, UPB_SIZE(12, 12), 3, 0, 5, _UPB_MODE_SCALAR},
4109
+ {4, UPB_SIZE(4, 4), 4, 0, 14, _UPB_MODE_SCALAR},
4110
+ {5, UPB_SIZE(8, 8), 5, 0, 14, _UPB_MODE_SCALAR},
4111
+ {6, UPB_SIZE(40, 56), 6, 0, 12, _UPB_MODE_SCALAR},
4112
+ {7, UPB_SIZE(48, 72), 7, 0, 12, _UPB_MODE_SCALAR},
4113
+ {8, UPB_SIZE(64, 104), 8, 0, 11, _UPB_MODE_SCALAR},
4114
+ {9, UPB_SIZE(16, 16), 9, 0, 5, _UPB_MODE_SCALAR},
4115
+ {10, UPB_SIZE(56, 88), 10, 0, 12, _UPB_MODE_SCALAR},
4116
+ {17, UPB_SIZE(20, 20), 11, 0, 8, _UPB_MODE_SCALAR},
3838
4117
  };
3839
4118
 
3840
4119
  const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = {
3841
4120
  &google_protobuf_FieldDescriptorProto_submsgs[0],
3842
4121
  &google_protobuf_FieldDescriptorProto__fields[0],
3843
- UPB_SIZE(72, 112), 11, false, 255,
4122
+ UPB_SIZE(72, 112), 11, false, 10, 255,
3844
4123
  };
3845
4124
 
3846
4125
  static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = {
@@ -3848,14 +4127,14 @@ static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1
3848
4127
  };
3849
4128
 
3850
4129
  static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2] = {
3851
- {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
3852
- {2, UPB_SIZE(12, 24), 2, 0, 11, 1},
4130
+ {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4131
+ {2, UPB_SIZE(12, 24), 2, 0, 11, _UPB_MODE_SCALAR},
3853
4132
  };
3854
4133
 
3855
4134
  const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = {
3856
4135
  &google_protobuf_OneofDescriptorProto_submsgs[0],
3857
4136
  &google_protobuf_OneofDescriptorProto__fields[0],
3858
- UPB_SIZE(16, 32), 2, false, 255,
4137
+ UPB_SIZE(16, 32), 2, false, 2, 255,
3859
4138
  };
3860
4139
 
3861
4140
  static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3] = {
@@ -3865,28 +4144,28 @@ static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3]
3865
4144
  };
3866
4145
 
3867
4146
  static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5] = {
3868
- {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
3869
- {2, UPB_SIZE(16, 32), 0, 2, 11, 3},
3870
- {3, UPB_SIZE(12, 24), 2, 1, 11, 1},
3871
- {4, UPB_SIZE(20, 40), 0, 0, 11, 3},
3872
- {5, UPB_SIZE(24, 48), 0, 0, 12, 3},
4147
+ {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4148
+ {2, UPB_SIZE(16, 32), 0, 2, 11, _UPB_MODE_ARRAY},
4149
+ {3, UPB_SIZE(12, 24), 2, 1, 11, _UPB_MODE_SCALAR},
4150
+ {4, UPB_SIZE(20, 40), 0, 0, 11, _UPB_MODE_ARRAY},
4151
+ {5, UPB_SIZE(24, 48), 0, 0, 12, _UPB_MODE_ARRAY},
3873
4152
  };
3874
4153
 
3875
4154
  const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = {
3876
4155
  &google_protobuf_EnumDescriptorProto_submsgs[0],
3877
4156
  &google_protobuf_EnumDescriptorProto__fields[0],
3878
- UPB_SIZE(32, 64), 5, false, 255,
4157
+ UPB_SIZE(32, 64), 5, false, 5, 255,
3879
4158
  };
3880
4159
 
3881
4160
  static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = {
3882
- {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
3883
- {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
4161
+ {1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR},
4162
+ {2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR},
3884
4163
  };
3885
4164
 
3886
4165
  const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = {
3887
4166
  NULL,
3888
4167
  &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0],
3889
- UPB_SIZE(16, 16), 2, false, 255,
4168
+ UPB_SIZE(16, 16), 2, false, 2, 255,
3890
4169
  };
3891
4170
 
3892
4171
  static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1] = {
@@ -3894,15 +4173,15 @@ static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_subms
3894
4173
  };
3895
4174
 
3896
4175
  static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = {
3897
- {1, UPB_SIZE(8, 8), 1, 0, 12, 1},
3898
- {2, UPB_SIZE(4, 4), 2, 0, 5, 1},
3899
- {3, UPB_SIZE(16, 24), 3, 0, 11, 1},
4176
+ {1, UPB_SIZE(8, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4177
+ {2, UPB_SIZE(4, 4), 2, 0, 5, _UPB_MODE_SCALAR},
4178
+ {3, UPB_SIZE(16, 24), 3, 0, 11, _UPB_MODE_SCALAR},
3900
4179
  };
3901
4180
 
3902
4181
  const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = {
3903
4182
  &google_protobuf_EnumValueDescriptorProto_submsgs[0],
3904
4183
  &google_protobuf_EnumValueDescriptorProto__fields[0],
3905
- UPB_SIZE(24, 32), 3, false, 255,
4184
+ UPB_SIZE(24, 32), 3, false, 3, 255,
3906
4185
  };
3907
4186
 
3908
4187
  static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2] = {
@@ -3911,15 +4190,15 @@ static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs
3911
4190
  };
3912
4191
 
3913
4192
  static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[3] = {
3914
- {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
3915
- {2, UPB_SIZE(16, 32), 0, 0, 11, 3},
3916
- {3, UPB_SIZE(12, 24), 2, 1, 11, 1},
4193
+ {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4194
+ {2, UPB_SIZE(16, 32), 0, 0, 11, _UPB_MODE_ARRAY},
4195
+ {3, UPB_SIZE(12, 24), 2, 1, 11, _UPB_MODE_SCALAR},
3917
4196
  };
3918
4197
 
3919
4198
  const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = {
3920
4199
  &google_protobuf_ServiceDescriptorProto_submsgs[0],
3921
4200
  &google_protobuf_ServiceDescriptorProto__fields[0],
3922
- UPB_SIZE(24, 48), 3, false, 255,
4201
+ UPB_SIZE(24, 48), 3, false, 3, 255,
3923
4202
  };
3924
4203
 
3925
4204
  static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1] = {
@@ -3927,18 +4206,18 @@ static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[
3927
4206
  };
3928
4207
 
3929
4208
  static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = {
3930
- {1, UPB_SIZE(4, 8), 1, 0, 12, 1},
3931
- {2, UPB_SIZE(12, 24), 2, 0, 12, 1},
3932
- {3, UPB_SIZE(20, 40), 3, 0, 12, 1},
3933
- {4, UPB_SIZE(28, 56), 4, 0, 11, 1},
3934
- {5, UPB_SIZE(1, 1), 5, 0, 8, 1},
3935
- {6, UPB_SIZE(2, 2), 6, 0, 8, 1},
4209
+ {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4210
+ {2, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR},
4211
+ {3, UPB_SIZE(20, 40), 3, 0, 12, _UPB_MODE_SCALAR},
4212
+ {4, UPB_SIZE(28, 56), 4, 0, 11, _UPB_MODE_SCALAR},
4213
+ {5, UPB_SIZE(1, 1), 5, 0, 8, _UPB_MODE_SCALAR},
4214
+ {6, UPB_SIZE(2, 2), 6, 0, 8, _UPB_MODE_SCALAR},
3936
4215
  };
3937
4216
 
3938
4217
  const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = {
3939
4218
  &google_protobuf_MethodDescriptorProto_submsgs[0],
3940
4219
  &google_protobuf_MethodDescriptorProto__fields[0],
3941
- UPB_SIZE(32, 64), 6, false, 255,
4220
+ UPB_SIZE(32, 64), 6, false, 6, 255,
3942
4221
  };
3943
4222
 
3944
4223
  static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = {
@@ -3946,33 +4225,33 @@ static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = {
3946
4225
  };
3947
4226
 
3948
4227
  static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = {
3949
- {1, UPB_SIZE(20, 24), 1, 0, 12, 1},
3950
- {8, UPB_SIZE(28, 40), 2, 0, 12, 1},
3951
- {9, UPB_SIZE(4, 4), 3, 0, 14, 1},
3952
- {10, UPB_SIZE(8, 8), 4, 0, 8, 1},
3953
- {11, UPB_SIZE(36, 56), 5, 0, 12, 1},
3954
- {16, UPB_SIZE(9, 9), 6, 0, 8, 1},
3955
- {17, UPB_SIZE(10, 10), 7, 0, 8, 1},
3956
- {18, UPB_SIZE(11, 11), 8, 0, 8, 1},
3957
- {20, UPB_SIZE(12, 12), 9, 0, 8, 1},
3958
- {23, UPB_SIZE(13, 13), 10, 0, 8, 1},
3959
- {27, UPB_SIZE(14, 14), 11, 0, 8, 1},
3960
- {31, UPB_SIZE(15, 15), 12, 0, 8, 1},
3961
- {36, UPB_SIZE(44, 72), 13, 0, 12, 1},
3962
- {37, UPB_SIZE(52, 88), 14, 0, 12, 1},
3963
- {39, UPB_SIZE(60, 104), 15, 0, 12, 1},
3964
- {40, UPB_SIZE(68, 120), 16, 0, 12, 1},
3965
- {41, UPB_SIZE(76, 136), 17, 0, 12, 1},
3966
- {42, UPB_SIZE(16, 16), 18, 0, 8, 1},
3967
- {44, UPB_SIZE(84, 152), 19, 0, 12, 1},
3968
- {45, UPB_SIZE(92, 168), 20, 0, 12, 1},
3969
- {999, UPB_SIZE(100, 184), 0, 0, 11, 3},
4228
+ {1, UPB_SIZE(20, 24), 1, 0, 12, _UPB_MODE_SCALAR},
4229
+ {8, UPB_SIZE(28, 40), 2, 0, 12, _UPB_MODE_SCALAR},
4230
+ {9, UPB_SIZE(4, 4), 3, 0, 14, _UPB_MODE_SCALAR},
4231
+ {10, UPB_SIZE(8, 8), 4, 0, 8, _UPB_MODE_SCALAR},
4232
+ {11, UPB_SIZE(36, 56), 5, 0, 12, _UPB_MODE_SCALAR},
4233
+ {16, UPB_SIZE(9, 9), 6, 0, 8, _UPB_MODE_SCALAR},
4234
+ {17, UPB_SIZE(10, 10), 7, 0, 8, _UPB_MODE_SCALAR},
4235
+ {18, UPB_SIZE(11, 11), 8, 0, 8, _UPB_MODE_SCALAR},
4236
+ {20, UPB_SIZE(12, 12), 9, 0, 8, _UPB_MODE_SCALAR},
4237
+ {23, UPB_SIZE(13, 13), 10, 0, 8, _UPB_MODE_SCALAR},
4238
+ {27, UPB_SIZE(14, 14), 11, 0, 8, _UPB_MODE_SCALAR},
4239
+ {31, UPB_SIZE(15, 15), 12, 0, 8, _UPB_MODE_SCALAR},
4240
+ {36, UPB_SIZE(44, 72), 13, 0, 12, _UPB_MODE_SCALAR},
4241
+ {37, UPB_SIZE(52, 88), 14, 0, 12, _UPB_MODE_SCALAR},
4242
+ {39, UPB_SIZE(60, 104), 15, 0, 12, _UPB_MODE_SCALAR},
4243
+ {40, UPB_SIZE(68, 120), 16, 0, 12, _UPB_MODE_SCALAR},
4244
+ {41, UPB_SIZE(76, 136), 17, 0, 12, _UPB_MODE_SCALAR},
4245
+ {42, UPB_SIZE(16, 16), 18, 0, 8, _UPB_MODE_SCALAR},
4246
+ {44, UPB_SIZE(84, 152), 19, 0, 12, _UPB_MODE_SCALAR},
4247
+ {45, UPB_SIZE(92, 168), 20, 0, 12, _UPB_MODE_SCALAR},
4248
+ {999, UPB_SIZE(100, 184), 0, 0, 11, _UPB_MODE_ARRAY},
3970
4249
  };
3971
4250
 
3972
4251
  const upb_msglayout google_protobuf_FileOptions_msginit = {
3973
4252
  &google_protobuf_FileOptions_submsgs[0],
3974
4253
  &google_protobuf_FileOptions__fields[0],
3975
- UPB_SIZE(104, 192), 21, false, 255,
4254
+ UPB_SIZE(104, 192), 21, false, 1, 255,
3976
4255
  };
3977
4256
 
3978
4257
  static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = {
@@ -3980,17 +4259,17 @@ static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = {
3980
4259
  };
3981
4260
 
3982
4261
  static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = {
3983
- {1, UPB_SIZE(1, 1), 1, 0, 8, 1},
3984
- {2, UPB_SIZE(2, 2), 2, 0, 8, 1},
3985
- {3, UPB_SIZE(3, 3), 3, 0, 8, 1},
3986
- {7, UPB_SIZE(4, 4), 4, 0, 8, 1},
3987
- {999, UPB_SIZE(8, 8), 0, 0, 11, 3},
4262
+ {1, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR},
4263
+ {2, UPB_SIZE(2, 2), 2, 0, 8, _UPB_MODE_SCALAR},
4264
+ {3, UPB_SIZE(3, 3), 3, 0, 8, _UPB_MODE_SCALAR},
4265
+ {7, UPB_SIZE(4, 4), 4, 0, 8, _UPB_MODE_SCALAR},
4266
+ {999, UPB_SIZE(8, 8), 0, 0, 11, _UPB_MODE_ARRAY},
3988
4267
  };
3989
4268
 
3990
4269
  const upb_msglayout google_protobuf_MessageOptions_msginit = {
3991
4270
  &google_protobuf_MessageOptions_submsgs[0],
3992
4271
  &google_protobuf_MessageOptions__fields[0],
3993
- UPB_SIZE(16, 16), 5, false, 255,
4272
+ UPB_SIZE(16, 16), 5, false, 3, 255,
3994
4273
  };
3995
4274
 
3996
4275
  static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = {
@@ -3998,19 +4277,19 @@ static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = {
3998
4277
  };
3999
4278
 
4000
4279
  static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = {
4001
- {1, UPB_SIZE(4, 4), 1, 0, 14, 1},
4002
- {2, UPB_SIZE(12, 12), 2, 0, 8, 1},
4003
- {3, UPB_SIZE(13, 13), 3, 0, 8, 1},
4004
- {5, UPB_SIZE(14, 14), 4, 0, 8, 1},
4005
- {6, UPB_SIZE(8, 8), 5, 0, 14, 1},
4006
- {10, UPB_SIZE(15, 15), 6, 0, 8, 1},
4007
- {999, UPB_SIZE(16, 16), 0, 0, 11, 3},
4280
+ {1, UPB_SIZE(4, 4), 1, 0, 14, _UPB_MODE_SCALAR},
4281
+ {2, UPB_SIZE(12, 12), 2, 0, 8, _UPB_MODE_SCALAR},
4282
+ {3, UPB_SIZE(13, 13), 3, 0, 8, _UPB_MODE_SCALAR},
4283
+ {5, UPB_SIZE(14, 14), 4, 0, 8, _UPB_MODE_SCALAR},
4284
+ {6, UPB_SIZE(8, 8), 5, 0, 14, _UPB_MODE_SCALAR},
4285
+ {10, UPB_SIZE(15, 15), 6, 0, 8, _UPB_MODE_SCALAR},
4286
+ {999, UPB_SIZE(16, 16), 0, 0, 11, _UPB_MODE_ARRAY},
4008
4287
  };
4009
4288
 
4010
4289
  const upb_msglayout google_protobuf_FieldOptions_msginit = {
4011
4290
  &google_protobuf_FieldOptions_submsgs[0],
4012
4291
  &google_protobuf_FieldOptions__fields[0],
4013
- UPB_SIZE(24, 24), 7, false, 255,
4292
+ UPB_SIZE(24, 24), 7, false, 3, 255,
4014
4293
  };
4015
4294
 
4016
4295
  static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = {
@@ -4018,13 +4297,13 @@ static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = {
4018
4297
  };
4019
4298
 
4020
4299
  static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = {
4021
- {999, UPB_SIZE(0, 0), 0, 0, 11, 3},
4300
+ {999, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
4022
4301
  };
4023
4302
 
4024
4303
  const upb_msglayout google_protobuf_OneofOptions_msginit = {
4025
4304
  &google_protobuf_OneofOptions_submsgs[0],
4026
4305
  &google_protobuf_OneofOptions__fields[0],
4027
- UPB_SIZE(8, 8), 1, false, 255,
4306
+ UPB_SIZE(8, 8), 1, false, 0, 255,
4028
4307
  };
4029
4308
 
4030
4309
  static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = {
@@ -4032,15 +4311,15 @@ static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = {
4032
4311
  };
4033
4312
 
4034
4313
  static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = {
4035
- {2, UPB_SIZE(1, 1), 1, 0, 8, 1},
4036
- {3, UPB_SIZE(2, 2), 2, 0, 8, 1},
4037
- {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
4314
+ {2, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR},
4315
+ {3, UPB_SIZE(2, 2), 2, 0, 8, _UPB_MODE_SCALAR},
4316
+ {999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY},
4038
4317
  };
4039
4318
 
4040
4319
  const upb_msglayout google_protobuf_EnumOptions_msginit = {
4041
4320
  &google_protobuf_EnumOptions_submsgs[0],
4042
4321
  &google_protobuf_EnumOptions__fields[0],
4043
- UPB_SIZE(8, 16), 3, false, 255,
4322
+ UPB_SIZE(8, 16), 3, false, 0, 255,
4044
4323
  };
4045
4324
 
4046
4325
  static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] = {
@@ -4048,14 +4327,14 @@ static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] =
4048
4327
  };
4049
4328
 
4050
4329
  static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = {
4051
- {1, UPB_SIZE(1, 1), 1, 0, 8, 1},
4052
- {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
4330
+ {1, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR},
4331
+ {999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY},
4053
4332
  };
4054
4333
 
4055
4334
  const upb_msglayout google_protobuf_EnumValueOptions_msginit = {
4056
4335
  &google_protobuf_EnumValueOptions_submsgs[0],
4057
4336
  &google_protobuf_EnumValueOptions__fields[0],
4058
- UPB_SIZE(8, 16), 2, false, 255,
4337
+ UPB_SIZE(8, 16), 2, false, 1, 255,
4059
4338
  };
4060
4339
 
4061
4340
  static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = {
@@ -4063,14 +4342,14 @@ static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = {
4063
4342
  };
4064
4343
 
4065
4344
  static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = {
4066
- {33, UPB_SIZE(1, 1), 1, 0, 8, 1},
4067
- {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
4345
+ {33, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR},
4346
+ {999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY},
4068
4347
  };
4069
4348
 
4070
4349
  const upb_msglayout google_protobuf_ServiceOptions_msginit = {
4071
4350
  &google_protobuf_ServiceOptions_submsgs[0],
4072
4351
  &google_protobuf_ServiceOptions__fields[0],
4073
- UPB_SIZE(8, 16), 2, false, 255,
4352
+ UPB_SIZE(8, 16), 2, false, 0, 255,
4074
4353
  };
4075
4354
 
4076
4355
  static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = {
@@ -4078,15 +4357,15 @@ static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = {
4078
4357
  };
4079
4358
 
4080
4359
  static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = {
4081
- {33, UPB_SIZE(8, 8), 1, 0, 8, 1},
4082
- {34, UPB_SIZE(4, 4), 2, 0, 14, 1},
4083
- {999, UPB_SIZE(12, 16), 0, 0, 11, 3},
4360
+ {33, UPB_SIZE(8, 8), 1, 0, 8, _UPB_MODE_SCALAR},
4361
+ {34, UPB_SIZE(4, 4), 2, 0, 14, _UPB_MODE_SCALAR},
4362
+ {999, UPB_SIZE(12, 16), 0, 0, 11, _UPB_MODE_ARRAY},
4084
4363
  };
4085
4364
 
4086
4365
  const upb_msglayout google_protobuf_MethodOptions_msginit = {
4087
4366
  &google_protobuf_MethodOptions_submsgs[0],
4088
4367
  &google_protobuf_MethodOptions__fields[0],
4089
- UPB_SIZE(16, 24), 3, false, 255,
4368
+ UPB_SIZE(16, 24), 3, false, 0, 255,
4090
4369
  };
4091
4370
 
4092
4371
  static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] = {
@@ -4094,30 +4373,30 @@ static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1]
4094
4373
  };
4095
4374
 
4096
4375
  static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = {
4097
- {2, UPB_SIZE(56, 80), 0, 0, 11, 3},
4098
- {3, UPB_SIZE(32, 32), 1, 0, 12, 1},
4099
- {4, UPB_SIZE(8, 8), 2, 0, 4, 1},
4100
- {5, UPB_SIZE(16, 16), 3, 0, 3, 1},
4101
- {6, UPB_SIZE(24, 24), 4, 0, 1, 1},
4102
- {7, UPB_SIZE(40, 48), 5, 0, 12, 1},
4103
- {8, UPB_SIZE(48, 64), 6, 0, 12, 1},
4376
+ {2, UPB_SIZE(56, 80), 0, 0, 11, _UPB_MODE_ARRAY},
4377
+ {3, UPB_SIZE(32, 32), 1, 0, 12, _UPB_MODE_SCALAR},
4378
+ {4, UPB_SIZE(8, 8), 2, 0, 4, _UPB_MODE_SCALAR},
4379
+ {5, UPB_SIZE(16, 16), 3, 0, 3, _UPB_MODE_SCALAR},
4380
+ {6, UPB_SIZE(24, 24), 4, 0, 1, _UPB_MODE_SCALAR},
4381
+ {7, UPB_SIZE(40, 48), 5, 0, 12, _UPB_MODE_SCALAR},
4382
+ {8, UPB_SIZE(48, 64), 6, 0, 12, _UPB_MODE_SCALAR},
4104
4383
  };
4105
4384
 
4106
4385
  const upb_msglayout google_protobuf_UninterpretedOption_msginit = {
4107
4386
  &google_protobuf_UninterpretedOption_submsgs[0],
4108
4387
  &google_protobuf_UninterpretedOption__fields[0],
4109
- UPB_SIZE(64, 96), 7, false, 255,
4388
+ UPB_SIZE(64, 96), 7, false, 0, 255,
4110
4389
  };
4111
4390
 
4112
4391
  static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = {
4113
- {1, UPB_SIZE(4, 8), 1, 0, 12, 2},
4114
- {2, UPB_SIZE(1, 1), 2, 0, 8, 2},
4392
+ {1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4393
+ {2, UPB_SIZE(1, 1), 2, 0, 8, _UPB_MODE_SCALAR},
4115
4394
  };
4116
4395
 
4117
4396
  const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = {
4118
4397
  NULL,
4119
4398
  &google_protobuf_UninterpretedOption_NamePart__fields[0],
4120
- UPB_SIZE(16, 32), 2, false, 255,
4399
+ UPB_SIZE(16, 32), 2, false, 2, 255,
4121
4400
  };
4122
4401
 
4123
4402
  static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = {
@@ -4125,27 +4404,27 @@ static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = {
4125
4404
  };
4126
4405
 
4127
4406
  static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = {
4128
- {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
4407
+ {1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
4129
4408
  };
4130
4409
 
4131
4410
  const upb_msglayout google_protobuf_SourceCodeInfo_msginit = {
4132
4411
  &google_protobuf_SourceCodeInfo_submsgs[0],
4133
4412
  &google_protobuf_SourceCodeInfo__fields[0],
4134
- UPB_SIZE(8, 8), 1, false, 255,
4413
+ UPB_SIZE(8, 8), 1, false, 1, 255,
4135
4414
  };
4136
4415
 
4137
4416
  static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = {
4138
- {1, UPB_SIZE(20, 40), 0, 0, 5, _UPB_LABEL_PACKED},
4139
- {2, UPB_SIZE(24, 48), 0, 0, 5, _UPB_LABEL_PACKED},
4140
- {3, UPB_SIZE(4, 8), 1, 0, 12, 1},
4141
- {4, UPB_SIZE(12, 24), 2, 0, 12, 1},
4142
- {6, UPB_SIZE(28, 56), 0, 0, 12, 3},
4417
+ {1, UPB_SIZE(20, 40), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED},
4418
+ {2, UPB_SIZE(24, 48), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED},
4419
+ {3, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
4420
+ {4, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR},
4421
+ {6, UPB_SIZE(28, 56), 0, 0, 12, _UPB_MODE_ARRAY},
4143
4422
  };
4144
4423
 
4145
4424
  const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = {
4146
4425
  NULL,
4147
4426
  &google_protobuf_SourceCodeInfo_Location__fields[0],
4148
- UPB_SIZE(32, 64), 5, false, 255,
4427
+ UPB_SIZE(32, 64), 5, false, 4, 255,
4149
4428
  };
4150
4429
 
4151
4430
  static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] = {
@@ -4153,26 +4432,26 @@ static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] =
4153
4432
  };
4154
4433
 
4155
4434
  static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] = {
4156
- {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
4435
+ {1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
4157
4436
  };
4158
4437
 
4159
4438
  const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = {
4160
4439
  &google_protobuf_GeneratedCodeInfo_submsgs[0],
4161
4440
  &google_protobuf_GeneratedCodeInfo__fields[0],
4162
- UPB_SIZE(8, 8), 1, false, 255,
4441
+ UPB_SIZE(8, 8), 1, false, 1, 255,
4163
4442
  };
4164
4443
 
4165
4444
  static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = {
4166
- {1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_LABEL_PACKED},
4167
- {2, UPB_SIZE(12, 16), 1, 0, 12, 1},
4168
- {3, UPB_SIZE(4, 4), 2, 0, 5, 1},
4169
- {4, UPB_SIZE(8, 8), 3, 0, 5, 1},
4445
+ {1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED},
4446
+ {2, UPB_SIZE(12, 16), 1, 0, 12, _UPB_MODE_SCALAR},
4447
+ {3, UPB_SIZE(4, 4), 2, 0, 5, _UPB_MODE_SCALAR},
4448
+ {4, UPB_SIZE(8, 8), 3, 0, 5, _UPB_MODE_SCALAR},
4170
4449
  };
4171
4450
 
4172
4451
  const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = {
4173
4452
  NULL,
4174
4453
  &google_protobuf_GeneratedCodeInfo_Annotation__fields[0],
4175
- UPB_SIZE(24, 48), 4, false, 255,
4454
+ UPB_SIZE(24, 48), 4, false, 4, 255,
4176
4455
  };
4177
4456
 
4178
4457
 
@@ -5167,13 +5446,44 @@ static int field_number_cmp(const void *p1, const void *p2) {
5167
5446
  return f1->number - f2->number;
5168
5447
  }
5169
5448
 
5170
- static void assign_layout_indices(const upb_msgdef *m, upb_msglayout_field *fields) {
5449
+ static void assign_layout_indices(const upb_msgdef *m, upb_msglayout *l,
5450
+ upb_msglayout_field *fields) {
5171
5451
  int i;
5172
5452
  int n = upb_msgdef_numfields(m);
5453
+ int dense_below = 0;
5173
5454
  for (i = 0; i < n; i++) {
5174
5455
  upb_fielddef *f = (upb_fielddef*)upb_msgdef_itof(m, fields[i].number);
5175
5456
  UPB_ASSERT(f);
5176
5457
  f->layout_index = i;
5458
+ if (i < UINT8_MAX && fields[i].number == i + 1 &&
5459
+ (i == 0 || fields[i-1].number == i)) {
5460
+ dense_below = i + 1;
5461
+ }
5462
+ }
5463
+ l->dense_below = dense_below;
5464
+ }
5465
+
5466
+ static void fill_fieldlayout(upb_msglayout_field *field, const upb_fielddef *f) {
5467
+ field->number = upb_fielddef_number(f);
5468
+ field->descriptortype = upb_fielddef_descriptortype(f);
5469
+
5470
+ if (field->descriptortype == UPB_DTYPE_STRING &&
5471
+ f->file->syntax == UPB_SYNTAX_PROTO2) {
5472
+ /* See TableDescriptorType() in upbc/generator.cc for details and
5473
+ * rationale. */
5474
+ field->descriptortype = UPB_DTYPE_BYTES;
5475
+ }
5476
+
5477
+ if (upb_fielddef_ismap(f)) {
5478
+ field->mode = _UPB_MODE_MAP;
5479
+ } else if (upb_fielddef_isseq(f)) {
5480
+ field->mode = _UPB_MODE_ARRAY;
5481
+ } else {
5482
+ field->mode = _UPB_MODE_SCALAR;
5483
+ }
5484
+
5485
+ if (upb_fielddef_packed(f)) {
5486
+ field->mode |= _UPB_MODE_IS_PACKED;
5177
5487
  }
5178
5488
  }
5179
5489
 
@@ -5218,8 +5528,8 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
5218
5528
  const upb_fielddef *val = upb_msgdef_itof(m, 2);
5219
5529
  fields[0].number = 1;
5220
5530
  fields[1].number = 2;
5221
- fields[0].label = UPB_LABEL_OPTIONAL;
5222
- fields[1].label = UPB_LABEL_OPTIONAL;
5531
+ fields[0].mode = _UPB_MODE_SCALAR;
5532
+ fields[1].mode = _UPB_MODE_SCALAR;
5223
5533
  fields[0].presence = 0;
5224
5534
  fields[1].presence = 0;
5225
5535
  fields[0].descriptortype = upb_fielddef_descriptortype(key);
@@ -5255,22 +5565,7 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
5255
5565
  upb_fielddef* f = upb_msg_iter_field(&it);
5256
5566
  upb_msglayout_field *field = &fields[upb_fielddef_index(f)];
5257
5567
 
5258
- field->number = upb_fielddef_number(f);
5259
- field->descriptortype = upb_fielddef_descriptortype(f);
5260
- field->label = upb_fielddef_label(f);
5261
-
5262
- if (field->descriptortype == UPB_DTYPE_STRING &&
5263
- f->file->syntax == UPB_SYNTAX_PROTO2) {
5264
- /* See TableDescriptorType() in upbc/generator.cc for details and
5265
- * rationale. */
5266
- field->descriptortype = UPB_DTYPE_BYTES;
5267
- }
5268
-
5269
- if (upb_fielddef_ismap(f)) {
5270
- field->label = _UPB_LABEL_MAP;
5271
- } else if (upb_fielddef_packed(f)) {
5272
- field->label = _UPB_LABEL_PACKED;
5273
- }
5568
+ fill_fieldlayout(field, f);
5274
5569
 
5275
5570
  if (upb_fielddef_issubmsg(f)) {
5276
5571
  const upb_msgdef *subm = upb_fielddef_msgsubdef(f);
@@ -5346,7 +5641,7 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
5346
5641
 
5347
5642
  /* Sort fields by number. */
5348
5643
  qsort(fields, upb_msgdef_numfields(m), sizeof(*fields), field_number_cmp);
5349
- assign_layout_indices(m, fields);
5644
+ assign_layout_indices(m, l, fields);
5350
5645
  }
5351
5646
 
5352
5647
  static char *strviewdup(symtab_addctx *ctx, upb_strview view) {
@@ -6056,13 +6351,18 @@ static void build_filedef(
6056
6351
  const upb_strview* strs;
6057
6352
  size_t i, n;
6058
6353
 
6059
- count_types_in_file(file_proto, file);
6354
+ file->symtab = ctx->symtab;
6060
6355
 
6356
+ /* One pass to count and allocate. */
6357
+ file->msg_count = 0;
6358
+ file->enum_count = 0;
6359
+ file->ext_count = 0;
6360
+ count_types_in_file(file_proto, file);
6061
6361
  file->msgs = symtab_alloc(ctx, sizeof(*file->msgs) * file->msg_count);
6062
6362
  file->enums = symtab_alloc(ctx, sizeof(*file->enums) * file->enum_count);
6063
6363
  file->exts = symtab_alloc(ctx, sizeof(*file->exts) * file->ext_count);
6064
6364
 
6065
- /* We increment these as defs are added. */
6365
+ /* In the second pass we increment these as defs are added. */
6066
6366
  file->msg_count = 0;
6067
6367
  file->enum_count = 0;
6068
6368
  file->ext_count = 0;
@@ -6191,41 +6491,43 @@ static void remove_filedef(upb_symtab *s, upb_filedef *file) {
6191
6491
  static const upb_filedef *_upb_symtab_addfile(
6192
6492
  upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
6193
6493
  const upb_msglayout **layouts, upb_status *status) {
6194
- upb_arena *file_arena = upb_arena_new();
6195
- upb_filedef *file;
6196
6494
  symtab_addctx ctx;
6495
+ upb_strview name = google_protobuf_FileDescriptorProto_name(file_proto);
6197
6496
 
6198
- if (!file_arena) return NULL;
6199
-
6200
- file = upb_arena_malloc(file_arena, sizeof(*file));
6201
- if (!file) goto done;
6497
+ if (upb_strtable_lookup2(&s->files, name.data, name.size, NULL)) {
6498
+ upb_status_seterrf(status, "duplicate file name (%.*s)",
6499
+ UPB_STRVIEW_ARGS(name));
6500
+ return NULL;
6501
+ }
6202
6502
 
6203
- ctx.file = file;
6204
6503
  ctx.symtab = s;
6205
- ctx.arena = file_arena;
6206
6504
  ctx.layouts = layouts;
6207
6505
  ctx.status = status;
6506
+ ctx.file = NULL;
6507
+ ctx.arena = upb_arena_new();
6208
6508
 
6209
- file->msg_count = 0;
6210
- file->enum_count = 0;
6211
- file->ext_count = 0;
6212
- file->symtab = s;
6509
+ if (!ctx.arena) {
6510
+ upb_status_setoom(status);
6511
+ return NULL;
6512
+ }
6213
6513
 
6214
6514
  if (UPB_UNLIKELY(UPB_SETJMP(ctx.err))) {
6215
6515
  UPB_ASSERT(!upb_ok(status));
6216
- remove_filedef(s, file);
6217
- file = NULL;
6516
+ if (ctx.file) {
6517
+ remove_filedef(s, ctx.file);
6518
+ ctx.file = NULL;
6519
+ }
6218
6520
  } else {
6219
- build_filedef(&ctx, file, file_proto);
6220
- upb_strtable_insert(&s->files, file->name, strlen(file->name),
6221
- upb_value_constptr(file), ctx.arena);
6521
+ ctx.file = symtab_alloc(&ctx, sizeof(*ctx.file));
6522
+ build_filedef(&ctx, ctx.file, file_proto);
6523
+ upb_strtable_insert(&s->files, name.data, name.size,
6524
+ upb_value_constptr(ctx.file), ctx.arena);
6222
6525
  UPB_ASSERT(upb_ok(status));
6223
- upb_arena_fuse(s->arena, file_arena);
6526
+ upb_arena_fuse(s->arena, ctx.arena);
6224
6527
  }
6225
6528
 
6226
- done:
6227
- upb_arena_free(file_arena);
6228
- return file;
6529
+ upb_arena_free(ctx.arena);
6530
+ return ctx.file;
6229
6531
  }
6230
6532
 
6231
6533
  const upb_filedef *upb_symtab_addfile(
@@ -6258,7 +6560,8 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) {
6258
6560
  }
6259
6561
 
6260
6562
  file = google_protobuf_FileDescriptorProto_parse_ex(
6261
- init->descriptor.data, init->descriptor.size, arena, UPB_DECODE_ALIAS);
6563
+ init->descriptor.data, init->descriptor.size, NULL, UPB_DECODE_ALIAS,
6564
+ arena);
6262
6565
  s->bytes_loaded += init->descriptor.size;
6263
6566
 
6264
6567
  if (!file) {
@@ -8388,7 +8691,17 @@ static void jsonenc_double(jsonenc *e, const char *fmt, double val) {
8388
8691
  } else if (val != val) {
8389
8692
  jsonenc_putstr(e, "\"NaN\"");
8390
8693
  } else {
8694
+ char *p = e->ptr;
8391
8695
  jsonenc_printf(e, fmt, val);
8696
+
8697
+ /* printf() is dependent on locales; sadly there is no easy and portable way
8698
+ * to avoid this. This little post-processing step will translate 1,2 -> 1.2
8699
+ * since JSON needs the latter. Arguably a hack, but it is simple and the
8700
+ * alternatives are far more complicated, platform-dependent, and/or larger
8701
+ * in code size. */
8702
+ for (char *end = e->ptr; p < end; p++) {
8703
+ if (*p == ',') *p = '.';
8704
+ }
8392
8705
  }
8393
8706
  }
8394
8707