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.
- checksums.yaml +4 -4
- data/ext/google/protobuf_c/extconf.rb +2 -3
- data/ext/google/protobuf_c/message.c +4 -13
- data/ext/google/protobuf_c/ruby-upb.c +360 -218
- data/ext/google/protobuf_c/ruby-upb.h +239 -210
- metadata +3 -3
@@ -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
|
645
|
-
|
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 +
|
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
|
-
|
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
|
-
|
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
|
6442
|
-
|
6443
|
-
|
6444
|
-
|
6445
|
-
|
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
|
-
|
6464
|
-
|
6465
|
-
|
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
|
-
|
6477
|
-
|
6478
|
-
|
6479
|
-
|
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
|
-
|
6495
|
-
|
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
|
-
|
6756
|
-
|
6757
|
-
|
6758
|
-
|
6759
|
-
|
6760
|
-
|
6761
|
-
|
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
|
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
|
-
|
7383
|
+
int hex_digit = TryGetHexDigit(src, end);
|
7291
7384
|
if (hex_digit < 0) {
|
7292
7385
|
_upb_DefBuilder_Errf(
|
7293
|
-
ctx, "\\x
|
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 (
|
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
|
8447
|
-
bool
|
8448
|
-
bool
|
8449
|
-
bool
|
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->
|
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->
|
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->
|
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->
|
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->
|
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->
|
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->
|
8930
|
-
|
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->
|
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->
|
9028
|
-
|
9029
|
-
|
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->
|
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
|
-
|
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
|
-
|
9075
|
-
|
9076
|
-
|
9077
|
-
|
9078
|
-
|
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
|
-
|
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
|
-
|
9095
|
-
|
9096
|
-
|
9097
|
-
|
9098
|
-
|
9099
|
-
|
9100
|
-
|
9101
|
-
|
9102
|
-
|
9103
|
-
|
9104
|
-
|
9105
|
-
|
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
|
-
|
9114
|
-
|
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:
|
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->
|
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(
|
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->
|
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
|
-
|
9489
|
-
|
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
|
-
|
9596
|
-
|
9597
|
-
|
9598
|
-
|
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
|
-
|
10240
|
-
|
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 =
|
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
|
-
|
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
|
-
|
11436
|
-
|
11437
|
-
|
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
|
-
|
11449
|
-
|
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
|
-
|
13634
|
-
|
13635
|
-
|
13636
|
-
|
13637
|
-
|
13638
|
-
|
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
|
}
|