Auto-generate files after cl/586542236

pull/14900/head
Protobuf Team Bot 1 year ago
parent c9653f5ad4
commit 07194fcfae
  1. 329
      php/ext/google/protobuf/php-upb.c
  2. 307
      php/ext/google/protobuf/php-upb.h
  3. 329
      ruby/ext/google/protobuf_c/ruby-upb.c
  4. 307
      ruby/ext/google/protobuf_c/ruby-upb.h

@ -181,6 +181,12 @@ Error, UINTPTR_MAX is undefined
#define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only
#ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY
#define UPB_ONLYBITS(x) x
#else
#define UPB_ONLYBITS(x) UPB_PRIVATE(x)
#endif
/* Configure whether fasttable is switched on or not. *************************/
#ifdef __has_attribute
@ -5885,14 +5891,14 @@ upb_MapInsertStatus upb_Message_InsertMapEntry(upb_Map* map,
upb_Message* map_entry_message,
upb_Arena* arena) {
// TODO: use a variant of upb_MiniTable_GetSubMessageTable() here.
const upb_MiniTable* map_entry_mini_table =
upb_MiniTableSub_Message(mini_table->subs[f->UPB_PRIVATE(submsg_index)]);
const upb_MiniTable* map_entry_mini_table = upb_MiniTableSub_Message(
mini_table->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]);
UPB_ASSERT(map_entry_mini_table);
UPB_ASSERT(map_entry_mini_table->field_count == 2);
UPB_ASSERT(map_entry_mini_table->UPB_PRIVATE(field_count) == 2);
const upb_MiniTableField* map_entry_key_field =
&map_entry_mini_table->fields[0];
&map_entry_mini_table->UPB_PRIVATE(fields)[0];
const upb_MiniTableField* map_entry_value_field =
&map_entry_mini_table->fields[1];
&map_entry_mini_table->UPB_PRIVATE(fields)[1];
// Map key/value cannot have explicit defaults,
// hence assuming a zero default is valid.
upb_MessageValue default_val;
@ -5975,7 +5981,7 @@ static bool upb_Clone_MessageValue(void* value, upb_CType value_type,
case kUpb_CType_Message: {
const upb_TaggedMessagePtr source = *(upb_TaggedMessagePtr*)value;
bool is_empty = upb_TaggedMessagePtr_IsEmpty(source);
if (is_empty) sub = &_kUpb_MiniTable_Empty;
if (is_empty) sub = UPB_PRIVATE(_upb_MiniTable_Empty)();
UPB_ASSERT(source);
upb_Message* clone = upb_Message_DeepClone(
_upb_TaggedMessagePtr_GetMessage(source), sub, arena);
@ -5998,7 +6004,8 @@ upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type,
upb_MessageValue key, val;
size_t iter = kUpb_Map_Begin;
while (upb_Map_Next(map, &key, &val, &iter)) {
const upb_MiniTableField* value_field = &map_entry_table->fields[1];
const upb_MiniTableField* value_field =
&map_entry_table->UPB_PRIVATE(fields)[1];
const upb_MiniTable* value_sub =
(value_field->UPB_PRIVATE(submsg_index) != kUpb_NoSub)
? upb_MiniTable_GetSubMessageTable(map_entry_table, value_field)
@ -6021,12 +6028,14 @@ static upb_Map* upb_Message_Map_DeepClone(const upb_Map* map,
upb_Message* clone,
upb_Arena* arena) {
// TODO: use a variant of upb_MiniTable_GetSubMessageTable() here.
const upb_MiniTable* map_entry_table =
upb_MiniTableSub_Message(mini_table->subs[f->UPB_PRIVATE(submsg_index)]);
const upb_MiniTable* map_entry_table = upb_MiniTableSub_Message(
mini_table->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]);
UPB_ASSERT(map_entry_table);
const upb_MiniTableField* key_field = &map_entry_table->fields[0];
const upb_MiniTableField* value_field = &map_entry_table->fields[1];
const upb_MiniTableField* key_field =
&map_entry_table->UPB_PRIVATE(fields)[0];
const upb_MiniTableField* value_field =
&map_entry_table->UPB_PRIVATE(fields)[1];
upb_Map* cloned_map = upb_Map_DeepClone(
map, upb_MiniTableField_CType(key_field),
@ -6094,8 +6103,8 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src,
upb_StringView empty_string = upb_StringView_FromDataAndSize(NULL, 0);
// Only copy message area skipping upb_Message_Internal.
memcpy(dst, src, mini_table->size);
for (size_t i = 0; i < mini_table->field_count; ++i) {
const upb_MiniTableField* field = &mini_table->fields[i];
for (size_t i = 0; i < mini_table->UPB_PRIVATE(field_count); ++i) {
const upb_MiniTableField* field = &mini_table->UPB_PRIVATE(fields)[i];
if (upb_MiniTableField_IsScalar(field)) {
switch (upb_MiniTableField_CType(field)) {
case kUpb_CType_Message: {
@ -6109,7 +6118,7 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src,
// decode status, or possible parse failure here.
bool is_empty = upb_TaggedMessagePtr_IsEmpty(tagged);
const upb_MiniTable* sub_message_table =
is_empty ? &_kUpb_MiniTable_Empty
is_empty ? UPB_PRIVATE(_upb_MiniTable_Empty)()
: upb_MiniTable_GetSubMessageTable(mini_table, field);
upb_Message* dst_sub_message =
upb_Message_DeepClone(sub_message, sub_message_table, arena);
@ -7203,16 +7212,16 @@ static const char* upb_MtDecoder_ParseModifier(upb_MtDecoder* d,
static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d,
upb_SubCounts sub_counts) {
uint32_t total_count = sub_counts.submsg_count + sub_counts.subenum_count;
size_t subs_bytes = sizeof(*d->table->subs) * total_count;
size_t subs_bytes = sizeof(*d->table->UPB_PRIVATE(subs)) * total_count;
upb_MiniTableSub* subs = upb_Arena_Malloc(d->arena, subs_bytes);
upb_MdDecoder_CheckOutOfMemory(&d->base, subs);
uint32_t i = 0;
for (; i < sub_counts.submsg_count; i++) {
subs[i].UPB_PRIVATE(submsg) = &_kUpb_MiniTable_Empty;
subs[i].UPB_PRIVATE(submsg) = UPB_PRIVATE(_upb_MiniTable_Empty)();
}
if (sub_counts.subenum_count) {
upb_MiniTableField* f = d->fields;
upb_MiniTableField* end_f = f + d->table->field_count;
upb_MiniTableField* end_f = f + d->table->UPB_PRIVATE(field_count);
for (; f < end_f; f++) {
if (f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum) {
f->UPB_PRIVATE(submsg_index) += sub_counts.submsg_count;
@ -7222,7 +7231,7 @@ static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d,
subs[i].UPB_PRIVATE(subenum) = NULL;
}
}
d->table->subs = subs;
d->table->UPB_PRIVATE(subs) = subs;
}
static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr,
@ -7253,7 +7262,7 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr,
ch <= kUpb_EncodedValue_MaxModifier) {
ptr = upb_MtDecoder_ParseModifier(d, ptr, ch, last_field, &msg_modifiers);
if (msg_modifiers & kUpb_MessageModifier_IsExtendable) {
d->table->ext |= kUpb_ExtMode_Extendable;
d->table->UPB_PRIVATE(ext) |= kUpb_ExtMode_Extendable;
}
} else if (ch == kUpb_EncodedValue_End) {
if (!d->table) {
@ -7263,7 +7272,7 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr,
} else if (kUpb_EncodedValue_MinSkip <= ch &&
ch <= kUpb_EncodedValue_MaxSkip) {
if (need_dense_below) {
d->table->dense_below = d->table->field_count;
d->table->UPB_PRIVATE(dense_below) = d->table->UPB_PRIVATE(field_count);
need_dense_below = false;
}
uint32_t skip;
@ -7278,7 +7287,7 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr,
}
if (need_dense_below) {
d->table->dense_below = d->table->field_count;
d->table->UPB_PRIVATE(dense_below) = d->table->UPB_PRIVATE(field_count);
}
return ptr;
@ -7292,14 +7301,14 @@ static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data,
upb_MdDecoder_CheckOutOfMemory(&d->base, d->fields);
upb_SubCounts sub_counts = {0, 0};
d->table->field_count = 0;
d->table->fields = d->fields;
d->table->UPB_PRIVATE(field_count) = 0;
d->table->UPB_PRIVATE(fields) = d->fields;
upb_MtDecoder_Parse(d, data, len, d->fields, sizeof(*d->fields),
&d->table->field_count, &sub_counts);
&d->table->UPB_PRIVATE(field_count), &sub_counts);
upb_Arena_ShrinkLast(d->arena, d->fields, sizeof(*d->fields) * len,
sizeof(*d->fields) * d->table->field_count);
d->table->fields = d->fields;
sizeof(*d->fields) * d->table->UPB_PRIVATE(field_count));
d->table->UPB_PRIVATE(fields) = d->fields;
upb_MtDecoder_AllocateSubs(d, sub_counts);
}
@ -7326,7 +7335,7 @@ int upb_MtDecoder_CompareFields(const void* _a, const void* _b) {
static bool upb_MtDecoder_SortLayoutItems(upb_MtDecoder* d) {
// Add items for all non-oneof fields (oneofs were already added).
int n = d->table->field_count;
int n = d->table->UPB_PRIVATE(field_count);
for (int i = 0; i < n; i++) {
upb_MiniTableField* f = &d->fields[i];
if (f->offset >= kOneofBase) continue;
@ -7350,27 +7359,29 @@ static size_t upb_MiniTable_DivideRoundUp(size_t n, size_t d) {
static void upb_MtDecoder_AssignHasbits(upb_MtDecoder* d) {
upb_MiniTable* ret = d->table;
int n = ret->field_count;
int n = ret->UPB_PRIVATE(field_count);
int last_hasbit = 0; // 0 cannot be used.
// First assign required fields, which must have the lowest hasbits.
for (int i = 0; i < n; i++) {
upb_MiniTableField* field = (upb_MiniTableField*)&ret->fields[i];
upb_MiniTableField* field =
(upb_MiniTableField*)&ret->UPB_PRIVATE(fields)[i];
if (field->offset == kRequiredPresence) {
field->presence = ++last_hasbit;
} else if (field->offset == kNoPresence) {
field->presence = 0;
}
}
ret->required_count = last_hasbit;
if (ret->required_count > 63) {
if (last_hasbit > 63) {
upb_MdDecoder_ErrorJmp(&d->base, "Too many required fields");
}
ret->UPB_PRIVATE(required_count) = last_hasbit;
// Next assign non-required hasbit fields.
for (int i = 0; i < n; i++) {
upb_MiniTableField* field = (upb_MiniTableField*)&ret->fields[i];
upb_MiniTableField* field =
(upb_MiniTableField*)&ret->UPB_PRIVATE(fields)[i];
if (field->offset == kHasbitPresence) {
field->presence = ++last_hasbit;
}
@ -7409,7 +7420,7 @@ static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) {
while (true) {
f->presence = ~item->offset;
if (f->offset == kUpb_LayoutItem_IndexSentinel) break;
UPB_ASSERT(f->offset - kOneofBase < d->table->field_count);
UPB_ASSERT(f->offset - kOneofBase < d->table->UPB_PRIVATE(field_count));
f = &d->fields[f->offset - kOneofBase];
}
}
@ -7477,9 +7488,9 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data,
upb_MtDecoder_ParseMessage(d, data, len);
upb_MtDecoder_AssignHasbits(d);
if (UPB_UNLIKELY(d->table->field_count != 2)) {
if (UPB_UNLIKELY(d->table->UPB_PRIVATE(field_count) != 2)) {
upb_MdDecoder_ErrorJmp(&d->base, "%hu fields in map",
d->table->field_count);
d->table->UPB_PRIVATE(field_count));
UPB_UNREACHABLE();
}
@ -7490,8 +7501,8 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data,
}
}
upb_MtDecoder_ValidateEntryField(d, &d->table->fields[0], 1);
upb_MtDecoder_ValidateEntryField(d, &d->table->fields[1], 2);
upb_MtDecoder_ValidateEntryField(d, &d->table->UPB_PRIVATE(fields)[0], 1);
upb_MtDecoder_ValidateEntryField(d, &d->table->UPB_PRIVATE(fields)[1], 2);
// Map entries have a pre-determined layout, regardless of types.
// NOTE: sync with mini_table/message_internal.h.
@ -7503,7 +7514,7 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data,
// Map entries have a special bit set to signal it's a map entry, used in
// upb_MiniTable_SetSubMessage() below.
d->table->ext |= kUpb_ExtMode_IsMapEntry;
d->table->UPB_PRIVATE(ext) |= kUpb_ExtMode_IsMapEntry;
}
static void upb_MtDecoder_ParseMessageSet(upb_MtDecoder* d, const char* data,
@ -7515,11 +7526,11 @@ static void upb_MtDecoder_ParseMessageSet(upb_MtDecoder* d, const char* data,
upb_MiniTable* ret = d->table;
ret->size = 0;
ret->field_count = 0;
ret->ext = kUpb_ExtMode_IsMessageSet;
ret->dense_below = 0;
ret->table_mask = -1;
ret->required_count = 0;
ret->UPB_PRIVATE(field_count) = 0;
ret->UPB_PRIVATE(ext) = kUpb_ExtMode_IsMessageSet;
ret->UPB_PRIVATE(dense_below) = 0;
ret->UPB_PRIVATE(table_mask) = -1;
ret->UPB_PRIVATE(required_count) = 0;
}
static upb_MiniTable* upb_MtDecoder_DoBuildMiniTableWithBuf(
@ -7528,11 +7539,11 @@ static upb_MiniTable* upb_MtDecoder_DoBuildMiniTableWithBuf(
upb_MdDecoder_CheckOutOfMemory(&decoder->base, decoder->table);
decoder->table->size = 0;
decoder->table->field_count = 0;
decoder->table->ext = kUpb_ExtMode_NonExtendable;
decoder->table->dense_below = 0;
decoder->table->table_mask = -1;
decoder->table->required_count = 0;
decoder->table->UPB_PRIVATE(field_count) = 0;
decoder->table->UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable;
decoder->table->UPB_PRIVATE(dense_below) = 0;
decoder->table->UPB_PRIVATE(table_mask) = -1;
decoder->table->UPB_PRIVATE(required_count) = 0;
// Strip off and verify the version tag.
if (!len--) goto done;
@ -7625,7 +7636,7 @@ static const char* upb_MtDecoder_DoBuildMiniTableExtension(
f->offset = 0;
f->presence = 0;
if (extendee->ext & kUpb_ExtMode_IsMessageSet) {
if (extendee->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMessageSet) {
// Extensions of MessageSet must be messages.
if (!upb_MiniTableField_IsSubMessage(f)) return NULL;
@ -7701,17 +7712,18 @@ upb_MiniTable* _upb_MiniTable_Build(const char* data, size_t len,
bool upb_MiniTable_SetSubMessage(upb_MiniTable* table,
upb_MiniTableField* field,
const upb_MiniTable* sub) {
UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field &&
(uintptr_t)field <
(uintptr_t)(table->fields + table->field_count));
UPB_ASSERT((uintptr_t)table->UPB_PRIVATE(fields) <= (uintptr_t)field &&
(uintptr_t)field < (uintptr_t)(table->UPB_PRIVATE(fields) +
table->UPB_PRIVATE(field_count)));
UPB_ASSERT(sub);
const bool sub_is_map = sub->ext & kUpb_ExtMode_IsMapEntry;
const bool sub_is_map = sub->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry;
switch (field->UPB_PRIVATE(descriptortype)) {
case kUpb_FieldType_Message:
if (sub_is_map) {
const bool table_is_map = table->ext & kUpb_ExtMode_IsMapEntry;
const bool table_is_map =
table->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry;
if (UPB_UNLIKELY(table_is_map)) return false;
field->mode = (field->mode & ~kUpb_FieldMode_Mask) | kUpb_FieldMode_Map;
@ -7727,23 +7739,23 @@ bool upb_MiniTable_SetSubMessage(upb_MiniTable* table,
}
upb_MiniTableSub* table_sub =
(void*)&table->subs[field->UPB_PRIVATE(submsg_index)];
(void*)&table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)];
// TODO: Add this assert back once YouTube is updated to not call
// this function repeatedly.
// UPB_ASSERT(table_sub->submsg == &_kUpb_MiniTable_Empty);
// UPB_ASSERT(UPB_PRIVATE(_upb_MiniTable_IsEmpty)(table_sub->submsg));
*table_sub = upb_MiniTableSub_FromMessage(sub);
return true;
}
bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field,
const upb_MiniTableEnum* sub) {
UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field &&
(uintptr_t)field <
(uintptr_t)(table->fields + table->field_count));
UPB_ASSERT((uintptr_t)table->UPB_PRIVATE(fields) <= (uintptr_t)field &&
(uintptr_t)field < (uintptr_t)(table->UPB_PRIVATE(fields) +
table->UPB_PRIVATE(field_count)));
UPB_ASSERT(sub);
upb_MiniTableSub* table_sub =
(void*)&table->subs[field->UPB_PRIVATE(submsg_index)];
(void*)&table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)];
*table_sub = upb_MiniTableSub_FromEnum(sub);
return true;
}
@ -7753,8 +7765,8 @@ uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt,
uint32_t msg_count = 0;
uint32_t enum_count = 0;
for (int i = 0; i < mt->field_count; i++) {
const upb_MiniTableField* f = &mt->fields[i];
for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) {
const upb_MiniTableField* f = &mt->UPB_PRIVATE(fields)[i];
if (upb_MiniTableField_CType(f) == kUpb_CType_Message) {
*subs = f;
++subs;
@ -7762,8 +7774,8 @@ uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt,
}
}
for (int i = 0; i < mt->field_count; i++) {
const upb_MiniTableField* f = &mt->fields[i];
for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) {
const upb_MiniTableField* f = &mt->UPB_PRIVATE(fields)[i];
if (upb_MiniTableField_CType(f) == kUpb_CType_Enum) {
*subs = f;
++subs;
@ -7784,8 +7796,8 @@ bool upb_MiniTable_Link(upb_MiniTable* mt, const upb_MiniTable** sub_tables,
uint32_t msg_count = 0;
uint32_t enum_count = 0;
for (int i = 0; i < mt->field_count; i++) {
upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i];
for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) {
upb_MiniTableField* f = (upb_MiniTableField*)&mt->UPB_PRIVATE(fields)[i];
if (upb_MiniTableField_CType(f) == kUpb_CType_Message) {
const upb_MiniTable* sub = sub_tables[msg_count++];
if (msg_count > sub_table_count) return false;
@ -7795,8 +7807,8 @@ bool upb_MiniTable_Link(upb_MiniTable* mt, const upb_MiniTable** sub_tables,
}
}
for (int i = 0; i < mt->field_count; i++) {
upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i];
for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) {
upb_MiniTableField* f = (upb_MiniTableField*)&mt->UPB_PRIVATE(fields)[i];
if (upb_MiniTableField_IsClosedEnum(f)) {
const upb_MiniTableEnum* sub = sub_enums[enum_count++];
if (enum_count > sub_enum_count) return false;
@ -8219,21 +8231,21 @@ const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup(
// Must be last.
const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
const upb_MiniTable* t, uint32_t number) {
const upb_MiniTable* m, uint32_t number) {
const size_t i = ((size_t)number) - 1; // 0 wraps to SIZE_MAX
// Ideal case: index into dense fields
if (i < t->dense_below) {
UPB_ASSERT(t->fields[i].number == number);
return &t->fields[i];
if (i < m->UPB_PRIVATE(dense_below)) {
UPB_ASSERT(m->UPB_PRIVATE(fields)[i].number == number);
return &m->UPB_PRIVATE(fields)[i];
}
// Slow case: binary search
int lo = t->dense_below;
int hi = t->field_count - 1;
int lo = m->UPB_PRIVATE(dense_below);
int hi = m->UPB_PRIVATE(field_count) - 1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
uint32_t num = t->fields[mid].number;
uint32_t num = m->UPB_PRIVATE(fields)[mid].number;
if (num < number) {
lo = mid + 1;
continue;
@ -8242,7 +8254,7 @@ const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
hi = mid - 1;
continue;
}
return &t->fields[mid];
return &m->UPB_PRIVATE(fields)[mid];
}
return NULL;
}
@ -8252,8 +8264,9 @@ const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m,
if (UPB_UNLIKELY(!upb_MiniTableField_IsInOneof(f))) {
return NULL;
}
const upb_MiniTableField* ptr = &m->fields[0];
const upb_MiniTableField* end = &m->fields[m->field_count];
const upb_MiniTableField* ptr = &m->UPB_PRIVATE(fields)[0];
const upb_MiniTableField* end =
&m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)];
for (; ptr < end; ptr++) {
if (ptr->presence == (*f).presence) {
return ptr;
@ -8265,7 +8278,8 @@ const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m,
bool upb_MiniTable_NextOneofField(const upb_MiniTable* m,
const upb_MiniTableField** f) {
const upb_MiniTableField* ptr = *f;
const upb_MiniTableField* end = &m->fields[m->field_count];
const upb_MiniTableField* end =
&m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)];
while (++ptr < end) {
if (ptr->presence == (*f)->presence) {
*f = ptr;
@ -8276,15 +8290,20 @@ bool upb_MiniTable_NextOneofField(const upb_MiniTable* m,
}
const struct upb_MiniTable _kUpb_MiniTable_Empty = {
.subs = NULL,
.fields = NULL,
#include <stddef.h>
// Must be last.
// A MiniTable for an empty message, used for unlinked sub-messages.
const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty) = {
.UPB_PRIVATE(subs) = NULL,
.UPB_PRIVATE(fields) = NULL,
.size = 0,
.field_count = 0,
.ext = kUpb_ExtMode_NonExtendable,
.dense_below = 0,
.table_mask = -1,
.required_count = 0,
.UPB_PRIVATE(field_count) = 0,
.UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable,
.UPB_PRIVATE(dense_below) = 0,
.UPB_PRIVATE(table_mask) = -1,
.UPB_PRIVATE(required_count) = 0,
};
@ -9587,7 +9606,7 @@ const upb_MiniTableField* upb_FieldDef_MiniTable(const upb_FieldDef* f) {
file, f->layout_index);
} else {
const upb_MiniTable* layout = upb_MessageDef_MiniTable(f->msgdef);
return &layout->fields[f->layout_index];
return &layout->UPB_PRIVATE(fields)[f->layout_index];
}
}
@ -11794,7 +11813,7 @@ void _upb_MessageDef_CreateMiniTable(upb_DefBuilder* ctx, upb_MessageDef* m) {
m->layout = _upb_MessageDef_MakeMiniTable(ctx, m);
} else {
m->layout = upb_MiniTableFile_Message(ctx->layout, ctx->msg_count++);
UPB_ASSERT(m->field_count == m->layout->field_count);
UPB_ASSERT(m->field_count == m->layout->UPB_PRIVATE(field_count));
// We don't need the result of this call, but it will assign layout_index
// for all the fields in O(n lg n) time.
@ -11830,9 +11849,9 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx,
UPB_ASSERT(layout_index < m->field_count);
upb_MiniTableField* mt_f =
(upb_MiniTableField*)&m->layout->fields[layout_index];
(upb_MiniTableField*)&m->layout->UPB_PRIVATE(fields)[layout_index];
if (sub_m) {
if (!mt->subs) {
if (!mt->UPB_PRIVATE(subs)) {
_upb_DefBuilder_Errf(ctx, "unexpected submsg for (%s)", m->full_name);
}
UPB_ASSERT(mt_f);
@ -11852,8 +11871,9 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx,
for (int i = 0; i < m->field_count; i++) {
const upb_FieldDef* f = upb_MessageDef_Field(m, i);
const int layout_index = _upb_FieldDef_LayoutIndex(f);
UPB_ASSERT(layout_index < m->layout->field_count);
const upb_MiniTableField* mt_f = &m->layout->fields[layout_index];
UPB_ASSERT(layout_index < m->layout->UPB_PRIVATE(field_count));
const upb_MiniTableField* mt_f =
&m->layout->UPB_PRIVATE(fields)[layout_index];
UPB_ASSERT(upb_FieldDef_Type(f) == upb_MiniTableField_Type(mt_f));
UPB_ASSERT(upb_FieldDef_CType(f) == upb_MiniTableField_CType(mt_f));
UPB_ASSERT(upb_FieldDef_HasPresence(f) ==
@ -12630,6 +12650,8 @@ typedef union {
// first argument, then we could just put them in mini_table/message.h as nice
// clean getters. But we don't have that so instead we gotta write these
// Frankenfunctions that take an array of subtables.
// TODO: Move these to mini_table/ anyway since there are other places
// that could use them.
// Returns the MiniTable corresponding to a given MiniTableField
// from an array of MiniTableSubs.
@ -12786,9 +12808,9 @@ static upb_Message* _upb_Decoder_NewSubMessage(upb_Decoder* d,
upb_Message* msg = _upb_Message_New(subl, &d->arena);
if (!msg) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
// Extensions should not be unlinked. A message extension should not be
// Extensions should not be unlinked. A message extension should not be
// registered until its sub-message type is available to be linked.
bool is_empty = subl == &_kUpb_MiniTable_Empty;
bool is_empty = UPB_PRIVATE(_upb_MiniTable_IsEmpty)(subl);
bool is_extension = field->mode & kUpb_LabelFlags_IsExtension;
UPB_ASSERT(!(is_empty && is_extension));
@ -12807,7 +12829,8 @@ static upb_Message* _upb_Decoder_ReuseSubMessage(
upb_TaggedMessagePtr tagged = *target;
const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field);
UPB_ASSERT(subl);
if (!upb_TaggedMessagePtr_IsEmpty(tagged) || subl == &_kUpb_MiniTable_Empty) {
if (!upb_TaggedMessagePtr_IsEmpty(tagged) ||
UPB_PRIVATE(_upb_MiniTable_IsEmpty)(subl)) {
return _upb_TaggedMessagePtr_GetMessage(tagged);
}
@ -13131,8 +13154,8 @@ upb_Map* _upb_Decoder_CreateMap(upb_Decoder* d, const upb_MiniTable* entry) {
[kUpb_FieldType_SInt64] = 8,
};
const upb_MiniTableField* key_field = &entry->fields[0];
const upb_MiniTableField* val_field = &entry->fields[1];
const upb_MiniTableField* key_field = &entry->UPB_PRIVATE(fields)[0];
const upb_MiniTableField* val_field = &entry->UPB_PRIVATE(fields)[1];
char key_size = kSizeInMap[key_field->UPB_PRIVATE(descriptortype)];
char val_size = kSizeInMap[val_field->UPB_PRIVATE(descriptortype)];
UPB_ASSERT(key_field->offset == offsetof(upb_MapEntryData, k));
@ -13154,9 +13177,9 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr,
const upb_MiniTable* entry = _upb_MiniTableSubs_MessageByField(subs, field);
UPB_ASSERT(entry);
UPB_ASSERT(entry->field_count == 2);
UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->fields[0]));
UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->fields[1]));
UPB_ASSERT(entry->UPB_PRIVATE(field_count) == 2);
UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->UPB_PRIVATE(fields)[0]));
UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->UPB_PRIVATE(fields)[1]));
if (!map) {
map = _upb_Decoder_CreateMap(d, entry);
@ -13166,11 +13189,14 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr,
// Parse map entry.
memset(&ent, 0, sizeof(ent));
if (entry->fields[1].UPB_PRIVATE(descriptortype) == kUpb_FieldType_Message ||
entry->fields[1].UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group) {
if (entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) ==
kUpb_FieldType_Message ||
entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) ==
kUpb_FieldType_Group) {
// Create proactively to handle the case where it doesn't appear.
upb_TaggedMessagePtr msg;
_upb_Decoder_NewSubMessage(d, entry->subs, &entry->fields[1], &msg);
_upb_Decoder_NewSubMessage(d, entry->UPB_PRIVATE(subs),
&entry->UPB_PRIVATE(fields)[1], &msg);
ent.data.v.val = upb_value_uintptr(msg);
}
@ -13271,15 +13297,15 @@ static const char* _upb_Decoder_DecodeToSubMessage(
UPB_NOINLINE
const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr,
const upb_Message* msg,
const upb_MiniTable* l) {
UPB_ASSERT(l->required_count);
const upb_MiniTable* m) {
UPB_ASSERT(m->UPB_PRIVATE(required_count));
if (UPB_LIKELY((d->options & kUpb_DecodeOption_CheckRequired) == 0)) {
return ptr;
}
uint64_t msg_head;
memcpy(&msg_head, msg, 8);
msg_head = _upb_BigEndian_Swap64(msg_head);
if (upb_MiniTable_requiredmask(l) & ~msg_head) {
if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) {
d->missing_required = true;
}
return ptr;
@ -13288,11 +13314,11 @@ const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr,
UPB_FORCEINLINE
static bool _upb_Decoder_TryFastDispatch(upb_Decoder* d, const char** ptr,
upb_Message* msg,
const upb_MiniTable* layout) {
const upb_MiniTable* m) {
#if UPB_FASTTABLE
if (layout && layout->table_mask != (unsigned char)-1) {
if (m && m->UPB_PRIVATE(table_mask) != (unsigned char)-1) {
uint16_t tag = _upb_FastDecoder_LoadTag(*ptr);
intptr_t table = decode_totable(layout);
intptr_t table = decode_totable(m);
*ptr = _upb_FastDecoder_TagDispatch(d, *ptr, msg, table, 0, tag);
return true;
}
@ -13448,30 +13474,30 @@ static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d,
if (t == NULL) return &none;
size_t idx = ((size_t)field_number) - 1; // 0 wraps to SIZE_MAX
if (idx < t->dense_below) {
if (idx < t->UPB_PRIVATE(dense_below)) {
/* Fastest case: index into dense fields. */
goto found;
}
if (t->dense_below < t->field_count) {
if (t->UPB_PRIVATE(dense_below) < t->UPB_PRIVATE(field_count)) {
/* Linear search non-dense fields. Resume scanning from last_field_index
* since fields are usually in order. */
size_t last = *last_field_index;
for (idx = last; idx < t->field_count; idx++) {
if (t->fields[idx].number == field_number) {
for (idx = last; idx < t->UPB_PRIVATE(field_count); idx++) {
if (t->UPB_PRIVATE(fields)[idx].number == field_number) {
goto found;
}
}
for (idx = t->dense_below; idx < last; idx++) {
if (t->fields[idx].number == field_number) {
for (idx = t->UPB_PRIVATE(dense_below); idx < last; idx++) {
if (t->UPB_PRIVATE(fields)[idx].number == field_number) {
goto found;
}
}
}
if (d->extreg) {
switch (t->ext) {
switch (t->UPB_PRIVATE(ext)) {
case kUpb_ExtMode_Extendable: {
const upb_MiniTableExtension* ext =
upb_ExtensionRegistry_Lookup(d->extreg, t, field_number);
@ -13491,9 +13517,9 @@ static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d,
return &none; /* Unknown field. */
found:
UPB_ASSERT(t->fields[idx].number == field_number);
UPB_ASSERT(t->UPB_PRIVATE(fields)[idx].number == field_number);
*last_field_index = idx;
return &t->fields[idx];
return &t->UPB_PRIVATE(fields)[idx];
}
int _upb_Decoder_GetVarintOp(const upb_MiniTableField* field) {
@ -13530,9 +13556,9 @@ static void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt,
// If sub-message is not linked, treat as unknown.
if (field->mode & kUpb_LabelFlags_IsExtension) return;
const upb_MiniTable* mt_sub =
_upb_MiniTableSubs_MessageByField(mt->subs, field);
_upb_MiniTableSubs_MessageByField(mt->UPB_PRIVATE(subs), field);
if ((d->options & kUpb_DecodeOption_ExperimentalAllowUnlinked) ||
mt_sub != &_kUpb_MiniTable_Empty) {
!UPB_PRIVATE(_upb_MiniTable_IsEmpty)(mt_sub)) {
return;
}
#ifndef NDEBUG
@ -13543,7 +13569,7 @@ static void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt,
do {
UPB_ASSERT(upb_MiniTableField_CType(oneof) == kUpb_CType_Message);
const upb_MiniTableSub* oneof_sub =
&mt->subs[oneof->UPB_PRIVATE(submsg_index)];
&mt->UPB_PRIVATE(subs)[oneof->UPB_PRIVATE(submsg_index)];
UPB_ASSERT(!oneof_sub);
} while (upb_MiniTable_NextOneofField(mt, &oneof));
}
@ -13671,7 +13697,7 @@ static const char* _upb_Decoder_DecodeKnownField(
upb_Decoder* d, const char* ptr, upb_Message* msg,
const upb_MiniTable* layout, const upb_MiniTableField* field, int op,
wireval* val) {
const upb_MiniTableSub* subs = layout->subs;
const upb_MiniTableSub* subs = layout->UPB_PRIVATE(subs);
uint8_t mode = field->mode;
if (UPB_UNLIKELY(mode & kUpb_LabelFlags_IsExtension)) {
@ -13825,7 +13851,7 @@ static const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr,
}
}
return UPB_UNLIKELY(layout && layout->required_count)
return UPB_UNLIKELY(layout && layout->UPB_PRIVATE(required_count))
? _upb_Decoder_CheckRequired(d, ptr, msg, layout)
: ptr;
}
@ -13961,9 +13987,9 @@ static const char* fastdecode_dispatch(UPB_PARSE_PARAMS) {
switch (upb_EpsCopyInputStream_IsDoneStatus(&d->input, ptr, &overrun)) {
case kUpb_IsDoneStatus_Done:
*(uint32_t*)msg |= hasbits; // Sync hasbits.
const upb_MiniTable* l = decode_totablep(table);
return UPB_UNLIKELY(l->required_count)
? _upb_Decoder_CheckRequired(d, ptr, msg, l)
const upb_MiniTable* m = decode_totablep(table);
return UPB_UNLIKELY(m->UPB_PRIVATE(required_count))
? _upb_Decoder_CheckRequired(d, ptr, msg, m)
: ptr;
case kUpb_IsDoneStatus_NotDone:
break;
@ -14812,12 +14838,12 @@ static const char* fastdecode_tosubmsg(upb_EpsCopyInputStream* e,
upb_Message** dst; \
uint32_t submsg_idx = (data >> 16) & 0xff; \
const upb_MiniTable* tablep = decode_totablep(table); \
const upb_MiniTable* subtablep = \
upb_MiniTableSub_Message(tablep->subs[submsg_idx]); \
const upb_MiniTable* subtablep = upb_MiniTableSub_Message( \
*UPB_PRIVATE(_upb_MiniTable_GetSubByIndex)(tablep, submsg_idx)); \
fastdecode_submsgdata submsg = {decode_totable(subtablep)}; \
fastdecode_arr farr; \
\
if (subtablep->table_mask == (uint8_t)-1) { \
if (subtablep->UPB_PRIVATE(table_mask) == (uint8_t)-1) { \
d->depth++; \
RETURN_GENERIC("submessage doesn't have fast tables."); \
} \
@ -15082,7 +15108,7 @@ static void encode_TaggedMessagePtr(upb_encstate* e,
upb_TaggedMessagePtr tagged,
const upb_MiniTable* m, size_t* size) {
if (upb_TaggedMessagePtr_IsEmpty(tagged)) {
m = &_kUpb_MiniTable_Empty;
m = UPB_PRIVATE(_upb_MiniTable_Empty)();
}
encode_message(e, _upb_TaggedMessagePtr_GetMessage(tagged), m, size);
}
@ -15283,12 +15309,12 @@ static void encode_array(upb_encstate* e, const upb_Message* msg,
static void encode_mapentry(upb_encstate* e, uint32_t number,
const upb_MiniTable* layout,
const upb_MapEntry* ent) {
const upb_MiniTableField* key_field = &layout->fields[0];
const upb_MiniTableField* val_field = &layout->fields[1];
const upb_MiniTableField* key_field = &layout->UPB_PRIVATE(fields)[0];
const upb_MiniTableField* val_field = &layout->UPB_PRIVATE(fields)[1];
size_t pre_len = e->limit - e->ptr;
size_t size;
encode_scalar(e, &ent->data.v, layout->subs, val_field);
encode_scalar(e, &ent->data.k, layout->subs, key_field);
encode_scalar(e, &ent->data.v, layout->UPB_PRIVATE(subs), val_field);
encode_scalar(e, &ent->data.k, layout->UPB_PRIVATE(subs), key_field);
size = (e->limit - e->ptr) - pre_len;
encode_varint(e, size);
encode_tag(e, number, kUpb_WireType_Delimited);
@ -15300,15 +15326,15 @@ static void encode_map(upb_encstate* e, const upb_Message* msg,
const upb_Map* map = *UPB_PTR_AT(msg, f->offset, const upb_Map*);
const upb_MiniTable* layout =
upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]);
UPB_ASSERT(layout->field_count == 2);
UPB_ASSERT(layout->UPB_PRIVATE(field_count) == 2);
if (map == NULL) return;
if (e->options & kUpb_EncodeOption_Deterministic) {
_upb_sortedmap sorted;
_upb_mapsorter_pushmap(&e->sorter,
layout->fields[0].UPB_PRIVATE(descriptortype), map,
&sorted);
_upb_mapsorter_pushmap(
&e->sorter, layout->UPB_PRIVATE(fields)[0].UPB_PRIVATE(descriptortype),
map, &sorted);
upb_MapEntry ent;
while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) {
encode_mapentry(e, f->number, layout, &ent);
@ -15410,11 +15436,12 @@ static void encode_message(upb_encstate* e, const upb_Message* msg,
const upb_MiniTable* m, size_t* size) {
size_t pre_len = e->limit - e->ptr;
if ((e->options & kUpb_EncodeOption_CheckRequired) && m->required_count) {
if ((e->options & kUpb_EncodeOption_CheckRequired) &&
m->UPB_PRIVATE(required_count)) {
uint64_t msg_head;
memcpy(&msg_head, msg, 8);
msg_head = _upb_BigEndian_Swap64(msg_head);
if (upb_MiniTable_requiredmask(m) & ~msg_head) {
if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) {
encode_err(e, kUpb_EncodeStatus_MissingRequired);
}
}
@ -15428,7 +15455,7 @@ static void encode_message(upb_encstate* e, const upb_Message* msg,
}
}
if (m->ext != kUpb_ExtMode_NonExtendable) {
if (m->UPB_PRIVATE(ext) != kUpb_ExtMode_NonExtendable) {
/* Encode all extensions together. Unlike C++, we do not attempt to keep
* these in field number order relative to normal fields or even to each
* other. */
@ -15439,25 +15466,26 @@ static void encode_message(upb_encstate* e, const upb_Message* msg,
_upb_sortedmap sorted;
_upb_mapsorter_pushexts(&e->sorter, ext, ext_count, &sorted);
while (_upb_sortedmap_nextext(&e->sorter, &sorted, &ext)) {
encode_ext(e, ext, m->ext == kUpb_ExtMode_IsMessageSet);
encode_ext(e, ext, m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet);
}
_upb_mapsorter_popmap(&e->sorter, &sorted);
} else {
const upb_Message_Extension* end = ext + ext_count;
for (; ext != end; ext++) {
encode_ext(e, ext, m->ext == kUpb_ExtMode_IsMessageSet);
encode_ext(e, ext, m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet);
}
}
}
}
if (m->field_count) {
const upb_MiniTableField* f = &m->fields[m->field_count];
const upb_MiniTableField* first = &m->fields[0];
if (m->UPB_PRIVATE(field_count)) {
const upb_MiniTableField* f =
&m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)];
const upb_MiniTableField* first = &m->UPB_PRIVATE(fields)[0];
while (f != first) {
f--;
if (encode_shouldencode(e, msg, m->subs, f)) {
encode_field(e, msg, m->subs, f);
if (encode_shouldencode(e, msg, m->UPB_PRIVATE(subs), f)) {
encode_field(e, msg, m->UPB_PRIVATE(subs), f);
}
}
}
@ -15598,3 +15626,4 @@ const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag,
#undef UPB_ATOMIC
#undef UPB_USE_C11_ATOMICS
#undef UPB_PRIVATE
#undef UPB_ONLYBITS

@ -180,6 +180,12 @@ Error, UINTPTR_MAX is undefined
#define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only
#ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY
#define UPB_ONLYBITS(x) x
#else
#define UPB_ONLYBITS(x) UPB_PRIVATE(x)
#endif
/* Configure whether fasttable is switched on or not. *************************/
#ifdef __has_attribute
@ -1309,82 +1315,6 @@ upb_MiniTableField_Type(const upb_MiniTableField* f) {
#define UPB_MINI_TABLE_INTERNAL_MESSAGE_H_
// Must be last.
struct upb_Decoder;
typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr,
upb_Message* msg, intptr_t table,
uint64_t hasbits, uint64_t data);
typedef struct {
uint64_t field_data;
_upb_FieldParser* field_parser;
} _upb_FastTable_Entry;
typedef enum {
kUpb_ExtMode_NonExtendable = 0, // Non-extendable message.
kUpb_ExtMode_Extendable = 1, // Normal extendable message.
kUpb_ExtMode_IsMessageSet = 2, // MessageSet message.
kUpb_ExtMode_IsMessageSet_ITEM =
3, // MessageSet item (temporary only, see decode.c)
// During table building we steal a bit to indicate that the message is a map
// entry. *Only* used during table building!
kUpb_ExtMode_IsMapEntry = 4,
} upb_ExtMode;
// upb_MiniTable represents the memory layout of a given upb_MessageDef.
// The members are public so generated code can initialize them,
// but users MUST NOT directly read or write any of its members.
struct upb_MiniTable {
const union upb_MiniTableSub* subs;
const struct upb_MiniTableField* fields;
// Must be aligned to sizeof(void*). Doesn't include internal members like
// unknown fields, extension dict, pointer to msglayout, etc.
uint16_t size;
uint16_t field_count;
uint8_t ext; // upb_ExtMode, declared as uint8_t so sizeof(ext) == 1
uint8_t dense_below;
uint8_t table_mask;
uint8_t required_count; // Required fields have the lowest hasbits.
// To statically initialize the tables of variable length, we need a flexible
// array member, and we need to compile in gnu99 mode (constant initialization
// of flexible array members is a GNU extension, not in C99 unfortunately.
_upb_FastTable_Entry fasttable[];
};
#ifdef __cplusplus
extern "C" {
#endif
// A MiniTable for an empty message, used for unlinked sub-messages.
extern const struct upb_MiniTable _kUpb_MiniTable_Empty;
// Computes a bitmask in which the |l->required_count| lowest bits are set,
// except that we skip the lowest bit (because upb never uses hasbit 0).
//
// Sample output:
// requiredmask(1) => 0b10 (0x2)
// requiredmask(5) => 0b111110 (0x3e)
UPB_INLINE uint64_t upb_MiniTable_requiredmask(const struct upb_MiniTable* l) {
int n = l->required_count;
assert(0 < n && n <= 63);
return ((1ULL << n) - 1) << 1;
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */
#ifndef UPB_MINI_TABLE_SUB_H_
#define UPB_MINI_TABLE_SUB_H_
#ifndef UPB_MINI_TABLE_INTERNAL_SUB_H_
#define UPB_MINI_TABLE_INTERNAL_SUB_H_
@ -1432,34 +1362,117 @@ UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTableSub_Message)(
// Must be last.
typedef union upb_MiniTableSub upb_MiniTableSub;
struct upb_Decoder;
typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr,
upb_Message* msg, intptr_t table,
uint64_t hasbits, uint64_t data);
typedef struct {
uint64_t field_data;
_upb_FieldParser* field_parser;
} _upb_FastTable_Entry;
typedef enum {
kUpb_ExtMode_NonExtendable = 0, // Non-extendable message.
kUpb_ExtMode_Extendable = 1, // Normal extendable message.
kUpb_ExtMode_IsMessageSet = 2, // MessageSet message.
kUpb_ExtMode_IsMessageSet_ITEM =
3, // MessageSet item (temporary only, see decode.c)
// During table building we steal a bit to indicate that the message is a map
// entry. *Only* used during table building!
kUpb_ExtMode_IsMapEntry = 4,
} upb_ExtMode;
// upb_MiniTable represents the memory layout of a given upb_MessageDef.
// The members are public so generated code can initialize them,
// but users MUST NOT directly read or write any of its members.
struct upb_MiniTable {
const union upb_MiniTableSub* UPB_PRIVATE(subs);
const struct upb_MiniTableField* UPB_ONLYBITS(fields);
// Must be aligned to sizeof(void*). Doesn't include internal members like
// unknown fields, extension dict, pointer to msglayout, etc.
uint16_t size;
uint16_t UPB_ONLYBITS(field_count);
uint8_t UPB_PRIVATE(ext); // upb_ExtMode, uint8_t here so sizeof(ext) == 1
uint8_t UPB_PRIVATE(dense_below);
uint8_t UPB_PRIVATE(table_mask);
uint8_t UPB_PRIVATE(required_count); // Required fields have the low hasbits.
// To statically initialize the tables of variable length, we need a flexible
// array member, and we need to compile in gnu99 mode (constant initialization
// of flexible array members is a GNU extension, not in C99 unfortunately.
_upb_FastTable_Entry UPB_PRIVATE(fasttable)[];
};
#ifdef __cplusplus
extern "C" {
#endif
// Constructors
UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTable_Empty)(void) {
extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty);
UPB_API_INLINE upb_MiniTableSub
upb_MiniTableSub_FromEnum(const struct upb_MiniTableEnum* subenum) {
return UPB_PRIVATE(_upb_MiniTableSub_FromEnum)(subenum);
return &UPB_PRIVATE(_kUpb_MiniTable_Empty);
}
UPB_API_INLINE upb_MiniTableSub
upb_MiniTableSub_FromMessage(const struct upb_MiniTable* submsg) {
return UPB_PRIVATE(_upb_MiniTableSub_FromMessage)(submsg);
UPB_INLINE int UPB_PRIVATE(_upb_MiniTable_FieldCount)(
const struct upb_MiniTable* m) {
return m->UPB_ONLYBITS(field_count);
}
// Getters
UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_IsEmpty)(
const struct upb_MiniTable* m) {
extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty);
UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTableSub_Enum(
upb_MiniTableSub sub) {
return UPB_PRIVATE(_upb_MiniTableSub_Enum)(sub);
return m == &UPB_PRIVATE(_kUpb_MiniTable_Empty);
}
UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableSub_Message(
upb_MiniTableSub sub) {
return UPB_PRIVATE(_upb_MiniTableSub_Message)(sub);
UPB_INLINE const struct upb_MiniTableField* UPB_PRIVATE(
_upb_MiniTable_GetFieldByIndex)(const struct upb_MiniTable* m, uint32_t i) {
return &m->UPB_ONLYBITS(fields)[i];
}
UPB_INLINE const union upb_MiniTableSub* UPB_PRIVATE(
_upb_MiniTable_GetSubByIndex)(const struct upb_MiniTable* m, uint32_t i) {
return &m->UPB_PRIVATE(subs)[i];
}
UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(
_upb_MiniTable_GetSubMessageTable)(const struct upb_MiniTable* m,
const struct upb_MiniTableField* f) {
UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_CType)(f) == kUpb_CType_Message);
const struct upb_MiniTable* ret = UPB_PRIVATE(_upb_MiniTableSub_Message)(
m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]);
UPB_ASSUME(ret);
return UPB_PRIVATE(_upb_MiniTable_IsEmpty)(ret) ? NULL : ret;
}
UPB_INLINE const struct upb_MiniTableEnum* UPB_PRIVATE(
_upb_MiniTable_GetSubEnumTable)(const struct upb_MiniTable* m,
const struct upb_MiniTableField* f) {
UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_CType)(f) == kUpb_CType_Enum);
return UPB_PRIVATE(_upb_MiniTableSub_Enum)(
m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]);
}
UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_MessageFieldIsLinked)(
const struct upb_MiniTable* m, const struct upb_MiniTableField* f) {
return UPB_PRIVATE(_upb_MiniTable_GetSubMessageTable)(m, f) != NULL;
}
// Computes a bitmask in which the |m->required_count| lowest bits are set,
// except that we skip the lowest bit (because upb never uses hasbit 0).
//
// Sample output:
// RequiredMask(1) => 0b10 (0x2)
// RequiredMask(5) => 0b111110 (0x3e)
UPB_INLINE uint64_t
UPB_PRIVATE(_upb_MiniTable_RequiredMask)(const struct upb_MiniTable* m) {
int n = m->UPB_PRIVATE(required_count);
UPB_ASSERT(0 < n && n <= 63);
return ((1ULL << n) - 1) << 1;
}
#ifdef __cplusplus
@ -1467,50 +1480,54 @@ UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableSub_Message(
#endif
#endif /* UPB_MINI_TABLE_SUB_H_ */
#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */
// Must be last.
typedef struct upb_MiniTable upb_MiniTable;
#ifdef __cplusplus
extern "C" {
#endif
typedef struct upb_MiniTable upb_MiniTable;
UPB_API const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
const upb_MiniTable* table, uint32_t number);
const upb_MiniTable* m, uint32_t number);
UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_GetFieldByIndex(
const upb_MiniTable* t, uint32_t index) {
return &t->fields[index];
const upb_MiniTable* m, uint32_t index) {
return UPB_PRIVATE(_upb_MiniTable_GetFieldByIndex)(m, index);
}
UPB_API_INLINE int upb_MiniTable_FieldCount(const upb_MiniTable* m) {
return UPB_PRIVATE(_upb_MiniTable_FieldCount)(m);
}
// Returns the MiniTable for this message field. If the field is unlinked,
// returns NULL.
// Returns the MiniTable for a message field, NULL if the field is unlinked.
UPB_API_INLINE const upb_MiniTable* upb_MiniTable_GetSubMessageTable(
const upb_MiniTable* mini_table, const upb_MiniTableField* field) {
UPB_ASSERT(upb_MiniTableField_CType(field) == kUpb_CType_Message);
const upb_MiniTable* ret = upb_MiniTableSub_Message(
mini_table->subs[field->UPB_PRIVATE(submsg_index)]);
UPB_ASSUME(ret);
return ret == &_kUpb_MiniTable_Empty ? NULL : ret;
const upb_MiniTable* m, const upb_MiniTableField* f) {
return UPB_PRIVATE(_upb_MiniTable_GetSubMessageTable)(m, f);
}
// Returns the MiniTableEnum for this enum field. If the field is unlinked,
// returns NULL.
// Returns the MiniTableEnum for a message field, NULL if the field is unlinked.
UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable(
const upb_MiniTable* mini_table, const upb_MiniTableField* f) {
UPB_ASSERT(upb_MiniTableField_CType(f) == kUpb_CType_Enum);
return upb_MiniTableSub_Enum(mini_table->subs[f->UPB_PRIVATE(submsg_index)]);
const upb_MiniTable* m, const upb_MiniTableField* f) {
return UPB_PRIVATE(_upb_MiniTable_GetSubEnumTable)(m, f);
}
// Returns true if this MiniTable field is linked to a MiniTable for the
// sub-message.
UPB_API_INLINE bool upb_MiniTable_MessageFieldIsLinked(
const upb_MiniTable* mini_table, const upb_MiniTableField* field) {
return upb_MiniTable_GetSubMessageTable(mini_table, field) != NULL;
const upb_MiniTable* m, const upb_MiniTableField* f) {
return UPB_PRIVATE(_upb_MiniTable_MessageFieldIsLinked)(m, f);
}
// TODO: Implement convenience getters for map entries:
//
// upb_MiniTable_GetMapKey()
// upb_MiniTable_GetMapValue()
// These could also assert that this is indeed a map entry (well, as best we
// can. We can assert that there are two fields with field numbers 1 and 2).
// If this field is in a oneof, returns the first field in the oneof.
//
// Otherwise returns NULL.
@ -2400,8 +2417,8 @@ struct upb_Message_InternalData {
/* Maps upb_CType -> memory size. */
extern char _upb_CTypeo_size[12];
UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* t) {
return t->size + sizeof(upb_Message_Internal);
UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* m) {
return m->size + sizeof(upb_Message_Internal);
}
// Inline version upb_Message_New(), for internal use.
@ -2897,6 +2914,49 @@ UPB_INLINE void UPB_PRIVATE(_upb_Array_Set)(upb_Array* array, size_t i,
#endif /* UPB_MESSAGE_INTERNAL_ARRAY_H_ */
#ifndef UPB_MINI_TABLE_SUB_H_
#define UPB_MINI_TABLE_SUB_H_
// Must be last.
typedef union upb_MiniTableSub upb_MiniTableSub;
#ifdef __cplusplus
extern "C" {
#endif
// Constructors
UPB_API_INLINE upb_MiniTableSub
upb_MiniTableSub_FromEnum(const struct upb_MiniTableEnum* subenum) {
return UPB_PRIVATE(_upb_MiniTableSub_FromEnum)(subenum);
}
UPB_API_INLINE upb_MiniTableSub
upb_MiniTableSub_FromMessage(const struct upb_MiniTable* submsg) {
return UPB_PRIVATE(_upb_MiniTableSub_FromMessage)(submsg);
}
// Getters
UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTableSub_Enum(
upb_MiniTableSub sub) {
return UPB_PRIVATE(_upb_MiniTableSub_Enum)(sub);
}
UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableSub_Message(
upb_MiniTableSub sub) {
return UPB_PRIVATE(_upb_MiniTableSub_Message)(sub);
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* UPB_MINI_TABLE_SUB_H_ */
// Must be last.
#ifdef __cplusplus
@ -3212,7 +3272,7 @@ UPB_API_INLINE void _upb_Message_SetTaggedMessagePtr(
UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte));
UPB_ASSUME(upb_MiniTableField_IsScalar(field));
UPB_ASSERT(upb_MiniTableSub_Message(
mini_table->subs[field->UPB_PRIVATE(submsg_index)]));
mini_table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]));
_upb_Message_SetNonExtensionField(msg, field, &sub_message);
}
@ -3232,7 +3292,7 @@ UPB_API_INLINE upb_Message* upb_Message_GetOrCreateMutableMessage(
upb_Message* sub_message = *UPB_PTR_AT(msg, field->offset, upb_Message*);
if (!sub_message) {
const upb_MiniTable* sub_mini_table = upb_MiniTableSub_Message(
mini_table->subs[field->UPB_PRIVATE(submsg_index)]);
mini_table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]);
UPB_ASSERT(sub_mini_table);
sub_message = _upb_Message_New(sub_mini_table, arena);
*UPB_PTR_AT(msg, field->offset, upb_Message*) = sub_message;
@ -3302,9 +3362,9 @@ UPB_API_INLINE upb_Map* upb_Message_GetOrCreateMutableMap(
const upb_MiniTableField* field, upb_Arena* arena) {
UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Message);
const upb_MiniTableField* map_entry_key_field =
&map_entry_mini_table->fields[0];
&map_entry_mini_table->UPB_PRIVATE(fields)[0];
const upb_MiniTableField* map_entry_value_field =
&map_entry_mini_table->fields[1];
&map_entry_mini_table->UPB_PRIVATE(fields)[1];
return _upb_Message_GetOrCreateMutableMap(
msg, field,
_upb_Map_CTypeSize(upb_MiniTableField_CType(map_entry_key_field)),
@ -13420,12 +13480,12 @@ non_ascii:
const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr,
const upb_Message* msg,
const upb_MiniTable* l);
const upb_MiniTable* m);
/* x86-64 pointers always have the high 16 bits matching. So we can shift
* left 8 and right 8 without loss of information. */
UPB_INLINE intptr_t decode_totable(const upb_MiniTable* tablep) {
return ((intptr_t)tablep << 8) | tablep->table_mask;
return ((intptr_t)tablep << 8) | tablep->UPB_PRIVATE(table_mask);
}
UPB_INLINE const upb_MiniTable* decode_totablep(intptr_t table) {
@ -13466,9 +13526,9 @@ const char* _upb_FastDecoder_TagDispatch(upb_Decoder* d, const char* ptr,
size_t idx = tag & mask;
UPB_ASSUME((idx & 7) == 0);
idx >>= 3;
data = table_p->fasttable[idx].field_data ^ tag;
UPB_MUSTTAIL return table_p->fasttable[idx].field_parser(d, ptr, msg, table,
hasbits, data);
data = table_p->UPB_PRIVATE(fasttable)[idx].field_data ^ tag;
UPB_MUSTTAIL return table_p->UPB_PRIVATE(fasttable)[idx].field_parser(
d, ptr, msg, table, hasbits, data);
}
#endif
@ -13778,3 +13838,4 @@ UPB_INLINE const char* upb_WireReader_SkipValue(
#undef UPB_ATOMIC
#undef UPB_USE_C11_ATOMICS
#undef UPB_PRIVATE
#undef UPB_ONLYBITS

@ -181,6 +181,12 @@ Error, UINTPTR_MAX is undefined
#define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only
#ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY
#define UPB_ONLYBITS(x) x
#else
#define UPB_ONLYBITS(x) UPB_PRIVATE(x)
#endif
/* Configure whether fasttable is switched on or not. *************************/
#ifdef __has_attribute
@ -5400,14 +5406,14 @@ upb_MapInsertStatus upb_Message_InsertMapEntry(upb_Map* map,
upb_Message* map_entry_message,
upb_Arena* arena) {
// TODO: use a variant of upb_MiniTable_GetSubMessageTable() here.
const upb_MiniTable* map_entry_mini_table =
upb_MiniTableSub_Message(mini_table->subs[f->UPB_PRIVATE(submsg_index)]);
const upb_MiniTable* map_entry_mini_table = upb_MiniTableSub_Message(
mini_table->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]);
UPB_ASSERT(map_entry_mini_table);
UPB_ASSERT(map_entry_mini_table->field_count == 2);
UPB_ASSERT(map_entry_mini_table->UPB_PRIVATE(field_count) == 2);
const upb_MiniTableField* map_entry_key_field =
&map_entry_mini_table->fields[0];
&map_entry_mini_table->UPB_PRIVATE(fields)[0];
const upb_MiniTableField* map_entry_value_field =
&map_entry_mini_table->fields[1];
&map_entry_mini_table->UPB_PRIVATE(fields)[1];
// Map key/value cannot have explicit defaults,
// hence assuming a zero default is valid.
upb_MessageValue default_val;
@ -5490,7 +5496,7 @@ static bool upb_Clone_MessageValue(void* value, upb_CType value_type,
case kUpb_CType_Message: {
const upb_TaggedMessagePtr source = *(upb_TaggedMessagePtr*)value;
bool is_empty = upb_TaggedMessagePtr_IsEmpty(source);
if (is_empty) sub = &_kUpb_MiniTable_Empty;
if (is_empty) sub = UPB_PRIVATE(_upb_MiniTable_Empty)();
UPB_ASSERT(source);
upb_Message* clone = upb_Message_DeepClone(
_upb_TaggedMessagePtr_GetMessage(source), sub, arena);
@ -5513,7 +5519,8 @@ upb_Map* upb_Map_DeepClone(const upb_Map* map, upb_CType key_type,
upb_MessageValue key, val;
size_t iter = kUpb_Map_Begin;
while (upb_Map_Next(map, &key, &val, &iter)) {
const upb_MiniTableField* value_field = &map_entry_table->fields[1];
const upb_MiniTableField* value_field =
&map_entry_table->UPB_PRIVATE(fields)[1];
const upb_MiniTable* value_sub =
(value_field->UPB_PRIVATE(submsg_index) != kUpb_NoSub)
? upb_MiniTable_GetSubMessageTable(map_entry_table, value_field)
@ -5536,12 +5543,14 @@ static upb_Map* upb_Message_Map_DeepClone(const upb_Map* map,
upb_Message* clone,
upb_Arena* arena) {
// TODO: use a variant of upb_MiniTable_GetSubMessageTable() here.
const upb_MiniTable* map_entry_table =
upb_MiniTableSub_Message(mini_table->subs[f->UPB_PRIVATE(submsg_index)]);
const upb_MiniTable* map_entry_table = upb_MiniTableSub_Message(
mini_table->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]);
UPB_ASSERT(map_entry_table);
const upb_MiniTableField* key_field = &map_entry_table->fields[0];
const upb_MiniTableField* value_field = &map_entry_table->fields[1];
const upb_MiniTableField* key_field =
&map_entry_table->UPB_PRIVATE(fields)[0];
const upb_MiniTableField* value_field =
&map_entry_table->UPB_PRIVATE(fields)[1];
upb_Map* cloned_map = upb_Map_DeepClone(
map, upb_MiniTableField_CType(key_field),
@ -5609,8 +5618,8 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src,
upb_StringView empty_string = upb_StringView_FromDataAndSize(NULL, 0);
// Only copy message area skipping upb_Message_Internal.
memcpy(dst, src, mini_table->size);
for (size_t i = 0; i < mini_table->field_count; ++i) {
const upb_MiniTableField* field = &mini_table->fields[i];
for (size_t i = 0; i < mini_table->UPB_PRIVATE(field_count); ++i) {
const upb_MiniTableField* field = &mini_table->UPB_PRIVATE(fields)[i];
if (upb_MiniTableField_IsScalar(field)) {
switch (upb_MiniTableField_CType(field)) {
case kUpb_CType_Message: {
@ -5624,7 +5633,7 @@ upb_Message* _upb_Message_Copy(upb_Message* dst, const upb_Message* src,
// decode status, or possible parse failure here.
bool is_empty = upb_TaggedMessagePtr_IsEmpty(tagged);
const upb_MiniTable* sub_message_table =
is_empty ? &_kUpb_MiniTable_Empty
is_empty ? UPB_PRIVATE(_upb_MiniTable_Empty)()
: upb_MiniTable_GetSubMessageTable(mini_table, field);
upb_Message* dst_sub_message =
upb_Message_DeepClone(sub_message, sub_message_table, arena);
@ -6718,16 +6727,16 @@ static const char* upb_MtDecoder_ParseModifier(upb_MtDecoder* d,
static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d,
upb_SubCounts sub_counts) {
uint32_t total_count = sub_counts.submsg_count + sub_counts.subenum_count;
size_t subs_bytes = sizeof(*d->table->subs) * total_count;
size_t subs_bytes = sizeof(*d->table->UPB_PRIVATE(subs)) * total_count;
upb_MiniTableSub* subs = upb_Arena_Malloc(d->arena, subs_bytes);
upb_MdDecoder_CheckOutOfMemory(&d->base, subs);
uint32_t i = 0;
for (; i < sub_counts.submsg_count; i++) {
subs[i].UPB_PRIVATE(submsg) = &_kUpb_MiniTable_Empty;
subs[i].UPB_PRIVATE(submsg) = UPB_PRIVATE(_upb_MiniTable_Empty)();
}
if (sub_counts.subenum_count) {
upb_MiniTableField* f = d->fields;
upb_MiniTableField* end_f = f + d->table->field_count;
upb_MiniTableField* end_f = f + d->table->UPB_PRIVATE(field_count);
for (; f < end_f; f++) {
if (f->UPB_PRIVATE(descriptortype) == kUpb_FieldType_Enum) {
f->UPB_PRIVATE(submsg_index) += sub_counts.submsg_count;
@ -6737,7 +6746,7 @@ static void upb_MtDecoder_AllocateSubs(upb_MtDecoder* d,
subs[i].UPB_PRIVATE(subenum) = NULL;
}
}
d->table->subs = subs;
d->table->UPB_PRIVATE(subs) = subs;
}
static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr,
@ -6768,7 +6777,7 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr,
ch <= kUpb_EncodedValue_MaxModifier) {
ptr = upb_MtDecoder_ParseModifier(d, ptr, ch, last_field, &msg_modifiers);
if (msg_modifiers & kUpb_MessageModifier_IsExtendable) {
d->table->ext |= kUpb_ExtMode_Extendable;
d->table->UPB_PRIVATE(ext) |= kUpb_ExtMode_Extendable;
}
} else if (ch == kUpb_EncodedValue_End) {
if (!d->table) {
@ -6778,7 +6787,7 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr,
} else if (kUpb_EncodedValue_MinSkip <= ch &&
ch <= kUpb_EncodedValue_MaxSkip) {
if (need_dense_below) {
d->table->dense_below = d->table->field_count;
d->table->UPB_PRIVATE(dense_below) = d->table->UPB_PRIVATE(field_count);
need_dense_below = false;
}
uint32_t skip;
@ -6793,7 +6802,7 @@ static const char* upb_MtDecoder_Parse(upb_MtDecoder* d, const char* ptr,
}
if (need_dense_below) {
d->table->dense_below = d->table->field_count;
d->table->UPB_PRIVATE(dense_below) = d->table->UPB_PRIVATE(field_count);
}
return ptr;
@ -6807,14 +6816,14 @@ static void upb_MtDecoder_ParseMessage(upb_MtDecoder* d, const char* data,
upb_MdDecoder_CheckOutOfMemory(&d->base, d->fields);
upb_SubCounts sub_counts = {0, 0};
d->table->field_count = 0;
d->table->fields = d->fields;
d->table->UPB_PRIVATE(field_count) = 0;
d->table->UPB_PRIVATE(fields) = d->fields;
upb_MtDecoder_Parse(d, data, len, d->fields, sizeof(*d->fields),
&d->table->field_count, &sub_counts);
&d->table->UPB_PRIVATE(field_count), &sub_counts);
upb_Arena_ShrinkLast(d->arena, d->fields, sizeof(*d->fields) * len,
sizeof(*d->fields) * d->table->field_count);
d->table->fields = d->fields;
sizeof(*d->fields) * d->table->UPB_PRIVATE(field_count));
d->table->UPB_PRIVATE(fields) = d->fields;
upb_MtDecoder_AllocateSubs(d, sub_counts);
}
@ -6841,7 +6850,7 @@ int upb_MtDecoder_CompareFields(const void* _a, const void* _b) {
static bool upb_MtDecoder_SortLayoutItems(upb_MtDecoder* d) {
// Add items for all non-oneof fields (oneofs were already added).
int n = d->table->field_count;
int n = d->table->UPB_PRIVATE(field_count);
for (int i = 0; i < n; i++) {
upb_MiniTableField* f = &d->fields[i];
if (f->offset >= kOneofBase) continue;
@ -6865,27 +6874,29 @@ static size_t upb_MiniTable_DivideRoundUp(size_t n, size_t d) {
static void upb_MtDecoder_AssignHasbits(upb_MtDecoder* d) {
upb_MiniTable* ret = d->table;
int n = ret->field_count;
int n = ret->UPB_PRIVATE(field_count);
int last_hasbit = 0; // 0 cannot be used.
// First assign required fields, which must have the lowest hasbits.
for (int i = 0; i < n; i++) {
upb_MiniTableField* field = (upb_MiniTableField*)&ret->fields[i];
upb_MiniTableField* field =
(upb_MiniTableField*)&ret->UPB_PRIVATE(fields)[i];
if (field->offset == kRequiredPresence) {
field->presence = ++last_hasbit;
} else if (field->offset == kNoPresence) {
field->presence = 0;
}
}
ret->required_count = last_hasbit;
if (ret->required_count > 63) {
if (last_hasbit > 63) {
upb_MdDecoder_ErrorJmp(&d->base, "Too many required fields");
}
ret->UPB_PRIVATE(required_count) = last_hasbit;
// Next assign non-required hasbit fields.
for (int i = 0; i < n; i++) {
upb_MiniTableField* field = (upb_MiniTableField*)&ret->fields[i];
upb_MiniTableField* field =
(upb_MiniTableField*)&ret->UPB_PRIVATE(fields)[i];
if (field->offset == kHasbitPresence) {
field->presence = ++last_hasbit;
}
@ -6924,7 +6935,7 @@ static void upb_MtDecoder_AssignOffsets(upb_MtDecoder* d) {
while (true) {
f->presence = ~item->offset;
if (f->offset == kUpb_LayoutItem_IndexSentinel) break;
UPB_ASSERT(f->offset - kOneofBase < d->table->field_count);
UPB_ASSERT(f->offset - kOneofBase < d->table->UPB_PRIVATE(field_count));
f = &d->fields[f->offset - kOneofBase];
}
}
@ -6992,9 +7003,9 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data,
upb_MtDecoder_ParseMessage(d, data, len);
upb_MtDecoder_AssignHasbits(d);
if (UPB_UNLIKELY(d->table->field_count != 2)) {
if (UPB_UNLIKELY(d->table->UPB_PRIVATE(field_count) != 2)) {
upb_MdDecoder_ErrorJmp(&d->base, "%hu fields in map",
d->table->field_count);
d->table->UPB_PRIVATE(field_count));
UPB_UNREACHABLE();
}
@ -7005,8 +7016,8 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data,
}
}
upb_MtDecoder_ValidateEntryField(d, &d->table->fields[0], 1);
upb_MtDecoder_ValidateEntryField(d, &d->table->fields[1], 2);
upb_MtDecoder_ValidateEntryField(d, &d->table->UPB_PRIVATE(fields)[0], 1);
upb_MtDecoder_ValidateEntryField(d, &d->table->UPB_PRIVATE(fields)[1], 2);
// Map entries have a pre-determined layout, regardless of types.
// NOTE: sync with mini_table/message_internal.h.
@ -7018,7 +7029,7 @@ static void upb_MtDecoder_ParseMap(upb_MtDecoder* d, const char* data,
// Map entries have a special bit set to signal it's a map entry, used in
// upb_MiniTable_SetSubMessage() below.
d->table->ext |= kUpb_ExtMode_IsMapEntry;
d->table->UPB_PRIVATE(ext) |= kUpb_ExtMode_IsMapEntry;
}
static void upb_MtDecoder_ParseMessageSet(upb_MtDecoder* d, const char* data,
@ -7030,11 +7041,11 @@ static void upb_MtDecoder_ParseMessageSet(upb_MtDecoder* d, const char* data,
upb_MiniTable* ret = d->table;
ret->size = 0;
ret->field_count = 0;
ret->ext = kUpb_ExtMode_IsMessageSet;
ret->dense_below = 0;
ret->table_mask = -1;
ret->required_count = 0;
ret->UPB_PRIVATE(field_count) = 0;
ret->UPB_PRIVATE(ext) = kUpb_ExtMode_IsMessageSet;
ret->UPB_PRIVATE(dense_below) = 0;
ret->UPB_PRIVATE(table_mask) = -1;
ret->UPB_PRIVATE(required_count) = 0;
}
static upb_MiniTable* upb_MtDecoder_DoBuildMiniTableWithBuf(
@ -7043,11 +7054,11 @@ static upb_MiniTable* upb_MtDecoder_DoBuildMiniTableWithBuf(
upb_MdDecoder_CheckOutOfMemory(&decoder->base, decoder->table);
decoder->table->size = 0;
decoder->table->field_count = 0;
decoder->table->ext = kUpb_ExtMode_NonExtendable;
decoder->table->dense_below = 0;
decoder->table->table_mask = -1;
decoder->table->required_count = 0;
decoder->table->UPB_PRIVATE(field_count) = 0;
decoder->table->UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable;
decoder->table->UPB_PRIVATE(dense_below) = 0;
decoder->table->UPB_PRIVATE(table_mask) = -1;
decoder->table->UPB_PRIVATE(required_count) = 0;
// Strip off and verify the version tag.
if (!len--) goto done;
@ -7140,7 +7151,7 @@ static const char* upb_MtDecoder_DoBuildMiniTableExtension(
f->offset = 0;
f->presence = 0;
if (extendee->ext & kUpb_ExtMode_IsMessageSet) {
if (extendee->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMessageSet) {
// Extensions of MessageSet must be messages.
if (!upb_MiniTableField_IsSubMessage(f)) return NULL;
@ -7216,17 +7227,18 @@ upb_MiniTable* _upb_MiniTable_Build(const char* data, size_t len,
bool upb_MiniTable_SetSubMessage(upb_MiniTable* table,
upb_MiniTableField* field,
const upb_MiniTable* sub) {
UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field &&
(uintptr_t)field <
(uintptr_t)(table->fields + table->field_count));
UPB_ASSERT((uintptr_t)table->UPB_PRIVATE(fields) <= (uintptr_t)field &&
(uintptr_t)field < (uintptr_t)(table->UPB_PRIVATE(fields) +
table->UPB_PRIVATE(field_count)));
UPB_ASSERT(sub);
const bool sub_is_map = sub->ext & kUpb_ExtMode_IsMapEntry;
const bool sub_is_map = sub->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry;
switch (field->UPB_PRIVATE(descriptortype)) {
case kUpb_FieldType_Message:
if (sub_is_map) {
const bool table_is_map = table->ext & kUpb_ExtMode_IsMapEntry;
const bool table_is_map =
table->UPB_PRIVATE(ext) & kUpb_ExtMode_IsMapEntry;
if (UPB_UNLIKELY(table_is_map)) return false;
field->mode = (field->mode & ~kUpb_FieldMode_Mask) | kUpb_FieldMode_Map;
@ -7242,23 +7254,23 @@ bool upb_MiniTable_SetSubMessage(upb_MiniTable* table,
}
upb_MiniTableSub* table_sub =
(void*)&table->subs[field->UPB_PRIVATE(submsg_index)];
(void*)&table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)];
// TODO: Add this assert back once YouTube is updated to not call
// this function repeatedly.
// UPB_ASSERT(table_sub->submsg == &_kUpb_MiniTable_Empty);
// UPB_ASSERT(UPB_PRIVATE(_upb_MiniTable_IsEmpty)(table_sub->submsg));
*table_sub = upb_MiniTableSub_FromMessage(sub);
return true;
}
bool upb_MiniTable_SetSubEnum(upb_MiniTable* table, upb_MiniTableField* field,
const upb_MiniTableEnum* sub) {
UPB_ASSERT((uintptr_t)table->fields <= (uintptr_t)field &&
(uintptr_t)field <
(uintptr_t)(table->fields + table->field_count));
UPB_ASSERT((uintptr_t)table->UPB_PRIVATE(fields) <= (uintptr_t)field &&
(uintptr_t)field < (uintptr_t)(table->UPB_PRIVATE(fields) +
table->UPB_PRIVATE(field_count)));
UPB_ASSERT(sub);
upb_MiniTableSub* table_sub =
(void*)&table->subs[field->UPB_PRIVATE(submsg_index)];
(void*)&table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)];
*table_sub = upb_MiniTableSub_FromEnum(sub);
return true;
}
@ -7268,8 +7280,8 @@ uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt,
uint32_t msg_count = 0;
uint32_t enum_count = 0;
for (int i = 0; i < mt->field_count; i++) {
const upb_MiniTableField* f = &mt->fields[i];
for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) {
const upb_MiniTableField* f = &mt->UPB_PRIVATE(fields)[i];
if (upb_MiniTableField_CType(f) == kUpb_CType_Message) {
*subs = f;
++subs;
@ -7277,8 +7289,8 @@ uint32_t upb_MiniTable_GetSubList(const upb_MiniTable* mt,
}
}
for (int i = 0; i < mt->field_count; i++) {
const upb_MiniTableField* f = &mt->fields[i];
for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) {
const upb_MiniTableField* f = &mt->UPB_PRIVATE(fields)[i];
if (upb_MiniTableField_CType(f) == kUpb_CType_Enum) {
*subs = f;
++subs;
@ -7299,8 +7311,8 @@ bool upb_MiniTable_Link(upb_MiniTable* mt, const upb_MiniTable** sub_tables,
uint32_t msg_count = 0;
uint32_t enum_count = 0;
for (int i = 0; i < mt->field_count; i++) {
upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i];
for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) {
upb_MiniTableField* f = (upb_MiniTableField*)&mt->UPB_PRIVATE(fields)[i];
if (upb_MiniTableField_CType(f) == kUpb_CType_Message) {
const upb_MiniTable* sub = sub_tables[msg_count++];
if (msg_count > sub_table_count) return false;
@ -7310,8 +7322,8 @@ bool upb_MiniTable_Link(upb_MiniTable* mt, const upb_MiniTable** sub_tables,
}
}
for (int i = 0; i < mt->field_count; i++) {
upb_MiniTableField* f = (upb_MiniTableField*)&mt->fields[i];
for (int i = 0; i < mt->UPB_PRIVATE(field_count); i++) {
upb_MiniTableField* f = (upb_MiniTableField*)&mt->UPB_PRIVATE(fields)[i];
if (upb_MiniTableField_IsClosedEnum(f)) {
const upb_MiniTableEnum* sub = sub_enums[enum_count++];
if (enum_count > sub_enum_count) return false;
@ -7734,21 +7746,21 @@ const upb_MiniTableExtension* upb_ExtensionRegistry_Lookup(
// Must be last.
const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
const upb_MiniTable* t, uint32_t number) {
const upb_MiniTable* m, uint32_t number) {
const size_t i = ((size_t)number) - 1; // 0 wraps to SIZE_MAX
// Ideal case: index into dense fields
if (i < t->dense_below) {
UPB_ASSERT(t->fields[i].number == number);
return &t->fields[i];
if (i < m->UPB_PRIVATE(dense_below)) {
UPB_ASSERT(m->UPB_PRIVATE(fields)[i].number == number);
return &m->UPB_PRIVATE(fields)[i];
}
// Slow case: binary search
int lo = t->dense_below;
int hi = t->field_count - 1;
int lo = m->UPB_PRIVATE(dense_below);
int hi = m->UPB_PRIVATE(field_count) - 1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
uint32_t num = t->fields[mid].number;
uint32_t num = m->UPB_PRIVATE(fields)[mid].number;
if (num < number) {
lo = mid + 1;
continue;
@ -7757,7 +7769,7 @@ const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
hi = mid - 1;
continue;
}
return &t->fields[mid];
return &m->UPB_PRIVATE(fields)[mid];
}
return NULL;
}
@ -7767,8 +7779,9 @@ const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m,
if (UPB_UNLIKELY(!upb_MiniTableField_IsInOneof(f))) {
return NULL;
}
const upb_MiniTableField* ptr = &m->fields[0];
const upb_MiniTableField* end = &m->fields[m->field_count];
const upb_MiniTableField* ptr = &m->UPB_PRIVATE(fields)[0];
const upb_MiniTableField* end =
&m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)];
for (; ptr < end; ptr++) {
if (ptr->presence == (*f).presence) {
return ptr;
@ -7780,7 +7793,8 @@ const upb_MiniTableField* upb_MiniTable_GetOneof(const upb_MiniTable* m,
bool upb_MiniTable_NextOneofField(const upb_MiniTable* m,
const upb_MiniTableField** f) {
const upb_MiniTableField* ptr = *f;
const upb_MiniTableField* end = &m->fields[m->field_count];
const upb_MiniTableField* end =
&m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)];
while (++ptr < end) {
if (ptr->presence == (*f)->presence) {
*f = ptr;
@ -7791,15 +7805,20 @@ bool upb_MiniTable_NextOneofField(const upb_MiniTable* m,
}
const struct upb_MiniTable _kUpb_MiniTable_Empty = {
.subs = NULL,
.fields = NULL,
#include <stddef.h>
// Must be last.
// A MiniTable for an empty message, used for unlinked sub-messages.
const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty) = {
.UPB_PRIVATE(subs) = NULL,
.UPB_PRIVATE(fields) = NULL,
.size = 0,
.field_count = 0,
.ext = kUpb_ExtMode_NonExtendable,
.dense_below = 0,
.table_mask = -1,
.required_count = 0,
.UPB_PRIVATE(field_count) = 0,
.UPB_PRIVATE(ext) = kUpb_ExtMode_NonExtendable,
.UPB_PRIVATE(dense_below) = 0,
.UPB_PRIVATE(table_mask) = -1,
.UPB_PRIVATE(required_count) = 0,
};
@ -9102,7 +9121,7 @@ const upb_MiniTableField* upb_FieldDef_MiniTable(const upb_FieldDef* f) {
file, f->layout_index);
} else {
const upb_MiniTable* layout = upb_MessageDef_MiniTable(f->msgdef);
return &layout->fields[f->layout_index];
return &layout->UPB_PRIVATE(fields)[f->layout_index];
}
}
@ -11309,7 +11328,7 @@ void _upb_MessageDef_CreateMiniTable(upb_DefBuilder* ctx, upb_MessageDef* m) {
m->layout = _upb_MessageDef_MakeMiniTable(ctx, m);
} else {
m->layout = upb_MiniTableFile_Message(ctx->layout, ctx->msg_count++);
UPB_ASSERT(m->field_count == m->layout->field_count);
UPB_ASSERT(m->field_count == m->layout->UPB_PRIVATE(field_count));
// We don't need the result of this call, but it will assign layout_index
// for all the fields in O(n lg n) time.
@ -11345,9 +11364,9 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx,
UPB_ASSERT(layout_index < m->field_count);
upb_MiniTableField* mt_f =
(upb_MiniTableField*)&m->layout->fields[layout_index];
(upb_MiniTableField*)&m->layout->UPB_PRIVATE(fields)[layout_index];
if (sub_m) {
if (!mt->subs) {
if (!mt->UPB_PRIVATE(subs)) {
_upb_DefBuilder_Errf(ctx, "unexpected submsg for (%s)", m->full_name);
}
UPB_ASSERT(mt_f);
@ -11367,8 +11386,9 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx,
for (int i = 0; i < m->field_count; i++) {
const upb_FieldDef* f = upb_MessageDef_Field(m, i);
const int layout_index = _upb_FieldDef_LayoutIndex(f);
UPB_ASSERT(layout_index < m->layout->field_count);
const upb_MiniTableField* mt_f = &m->layout->fields[layout_index];
UPB_ASSERT(layout_index < m->layout->UPB_PRIVATE(field_count));
const upb_MiniTableField* mt_f =
&m->layout->UPB_PRIVATE(fields)[layout_index];
UPB_ASSERT(upb_FieldDef_Type(f) == upb_MiniTableField_Type(mt_f));
UPB_ASSERT(upb_FieldDef_CType(f) == upb_MiniTableField_CType(mt_f));
UPB_ASSERT(upb_FieldDef_HasPresence(f) ==
@ -12145,6 +12165,8 @@ typedef union {
// first argument, then we could just put them in mini_table/message.h as nice
// clean getters. But we don't have that so instead we gotta write these
// Frankenfunctions that take an array of subtables.
// TODO: Move these to mini_table/ anyway since there are other places
// that could use them.
// Returns the MiniTable corresponding to a given MiniTableField
// from an array of MiniTableSubs.
@ -12301,9 +12323,9 @@ static upb_Message* _upb_Decoder_NewSubMessage(upb_Decoder* d,
upb_Message* msg = _upb_Message_New(subl, &d->arena);
if (!msg) _upb_Decoder_ErrorJmp(d, kUpb_DecodeStatus_OutOfMemory);
// Extensions should not be unlinked. A message extension should not be
// Extensions should not be unlinked. A message extension should not be
// registered until its sub-message type is available to be linked.
bool is_empty = subl == &_kUpb_MiniTable_Empty;
bool is_empty = UPB_PRIVATE(_upb_MiniTable_IsEmpty)(subl);
bool is_extension = field->mode & kUpb_LabelFlags_IsExtension;
UPB_ASSERT(!(is_empty && is_extension));
@ -12322,7 +12344,8 @@ static upb_Message* _upb_Decoder_ReuseSubMessage(
upb_TaggedMessagePtr tagged = *target;
const upb_MiniTable* subl = _upb_MiniTableSubs_MessageByField(subs, field);
UPB_ASSERT(subl);
if (!upb_TaggedMessagePtr_IsEmpty(tagged) || subl == &_kUpb_MiniTable_Empty) {
if (!upb_TaggedMessagePtr_IsEmpty(tagged) ||
UPB_PRIVATE(_upb_MiniTable_IsEmpty)(subl)) {
return _upb_TaggedMessagePtr_GetMessage(tagged);
}
@ -12646,8 +12669,8 @@ upb_Map* _upb_Decoder_CreateMap(upb_Decoder* d, const upb_MiniTable* entry) {
[kUpb_FieldType_SInt64] = 8,
};
const upb_MiniTableField* key_field = &entry->fields[0];
const upb_MiniTableField* val_field = &entry->fields[1];
const upb_MiniTableField* key_field = &entry->UPB_PRIVATE(fields)[0];
const upb_MiniTableField* val_field = &entry->UPB_PRIVATE(fields)[1];
char key_size = kSizeInMap[key_field->UPB_PRIVATE(descriptortype)];
char val_size = kSizeInMap[val_field->UPB_PRIVATE(descriptortype)];
UPB_ASSERT(key_field->offset == offsetof(upb_MapEntryData, k));
@ -12669,9 +12692,9 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr,
const upb_MiniTable* entry = _upb_MiniTableSubs_MessageByField(subs, field);
UPB_ASSERT(entry);
UPB_ASSERT(entry->field_count == 2);
UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->fields[0]));
UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->fields[1]));
UPB_ASSERT(entry->UPB_PRIVATE(field_count) == 2);
UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->UPB_PRIVATE(fields)[0]));
UPB_ASSERT(upb_MiniTableField_IsScalar(&entry->UPB_PRIVATE(fields)[1]));
if (!map) {
map = _upb_Decoder_CreateMap(d, entry);
@ -12681,11 +12704,14 @@ static const char* _upb_Decoder_DecodeToMap(upb_Decoder* d, const char* ptr,
// Parse map entry.
memset(&ent, 0, sizeof(ent));
if (entry->fields[1].UPB_PRIVATE(descriptortype) == kUpb_FieldType_Message ||
entry->fields[1].UPB_PRIVATE(descriptortype) == kUpb_FieldType_Group) {
if (entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) ==
kUpb_FieldType_Message ||
entry->UPB_PRIVATE(fields)[1].UPB_PRIVATE(descriptortype) ==
kUpb_FieldType_Group) {
// Create proactively to handle the case where it doesn't appear.
upb_TaggedMessagePtr msg;
_upb_Decoder_NewSubMessage(d, entry->subs, &entry->fields[1], &msg);
_upb_Decoder_NewSubMessage(d, entry->UPB_PRIVATE(subs),
&entry->UPB_PRIVATE(fields)[1], &msg);
ent.data.v.val = upb_value_uintptr(msg);
}
@ -12786,15 +12812,15 @@ static const char* _upb_Decoder_DecodeToSubMessage(
UPB_NOINLINE
const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr,
const upb_Message* msg,
const upb_MiniTable* l) {
UPB_ASSERT(l->required_count);
const upb_MiniTable* m) {
UPB_ASSERT(m->UPB_PRIVATE(required_count));
if (UPB_LIKELY((d->options & kUpb_DecodeOption_CheckRequired) == 0)) {
return ptr;
}
uint64_t msg_head;
memcpy(&msg_head, msg, 8);
msg_head = _upb_BigEndian_Swap64(msg_head);
if (upb_MiniTable_requiredmask(l) & ~msg_head) {
if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) {
d->missing_required = true;
}
return ptr;
@ -12803,11 +12829,11 @@ const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr,
UPB_FORCEINLINE
static bool _upb_Decoder_TryFastDispatch(upb_Decoder* d, const char** ptr,
upb_Message* msg,
const upb_MiniTable* layout) {
const upb_MiniTable* m) {
#if UPB_FASTTABLE
if (layout && layout->table_mask != (unsigned char)-1) {
if (m && m->UPB_PRIVATE(table_mask) != (unsigned char)-1) {
uint16_t tag = _upb_FastDecoder_LoadTag(*ptr);
intptr_t table = decode_totable(layout);
intptr_t table = decode_totable(m);
*ptr = _upb_FastDecoder_TagDispatch(d, *ptr, msg, table, 0, tag);
return true;
}
@ -12963,30 +12989,30 @@ static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d,
if (t == NULL) return &none;
size_t idx = ((size_t)field_number) - 1; // 0 wraps to SIZE_MAX
if (idx < t->dense_below) {
if (idx < t->UPB_PRIVATE(dense_below)) {
/* Fastest case: index into dense fields. */
goto found;
}
if (t->dense_below < t->field_count) {
if (t->UPB_PRIVATE(dense_below) < t->UPB_PRIVATE(field_count)) {
/* Linear search non-dense fields. Resume scanning from last_field_index
* since fields are usually in order. */
size_t last = *last_field_index;
for (idx = last; idx < t->field_count; idx++) {
if (t->fields[idx].number == field_number) {
for (idx = last; idx < t->UPB_PRIVATE(field_count); idx++) {
if (t->UPB_PRIVATE(fields)[idx].number == field_number) {
goto found;
}
}
for (idx = t->dense_below; idx < last; idx++) {
if (t->fields[idx].number == field_number) {
for (idx = t->UPB_PRIVATE(dense_below); idx < last; idx++) {
if (t->UPB_PRIVATE(fields)[idx].number == field_number) {
goto found;
}
}
}
if (d->extreg) {
switch (t->ext) {
switch (t->UPB_PRIVATE(ext)) {
case kUpb_ExtMode_Extendable: {
const upb_MiniTableExtension* ext =
upb_ExtensionRegistry_Lookup(d->extreg, t, field_number);
@ -13006,9 +13032,9 @@ static const upb_MiniTableField* _upb_Decoder_FindField(upb_Decoder* d,
return &none; /* Unknown field. */
found:
UPB_ASSERT(t->fields[idx].number == field_number);
UPB_ASSERT(t->UPB_PRIVATE(fields)[idx].number == field_number);
*last_field_index = idx;
return &t->fields[idx];
return &t->UPB_PRIVATE(fields)[idx];
}
int _upb_Decoder_GetVarintOp(const upb_MiniTableField* field) {
@ -13045,9 +13071,9 @@ static void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt,
// If sub-message is not linked, treat as unknown.
if (field->mode & kUpb_LabelFlags_IsExtension) return;
const upb_MiniTable* mt_sub =
_upb_MiniTableSubs_MessageByField(mt->subs, field);
_upb_MiniTableSubs_MessageByField(mt->UPB_PRIVATE(subs), field);
if ((d->options & kUpb_DecodeOption_ExperimentalAllowUnlinked) ||
mt_sub != &_kUpb_MiniTable_Empty) {
!UPB_PRIVATE(_upb_MiniTable_IsEmpty)(mt_sub)) {
return;
}
#ifndef NDEBUG
@ -13058,7 +13084,7 @@ static void _upb_Decoder_CheckUnlinked(upb_Decoder* d, const upb_MiniTable* mt,
do {
UPB_ASSERT(upb_MiniTableField_CType(oneof) == kUpb_CType_Message);
const upb_MiniTableSub* oneof_sub =
&mt->subs[oneof->UPB_PRIVATE(submsg_index)];
&mt->UPB_PRIVATE(subs)[oneof->UPB_PRIVATE(submsg_index)];
UPB_ASSERT(!oneof_sub);
} while (upb_MiniTable_NextOneofField(mt, &oneof));
}
@ -13186,7 +13212,7 @@ static const char* _upb_Decoder_DecodeKnownField(
upb_Decoder* d, const char* ptr, upb_Message* msg,
const upb_MiniTable* layout, const upb_MiniTableField* field, int op,
wireval* val) {
const upb_MiniTableSub* subs = layout->subs;
const upb_MiniTableSub* subs = layout->UPB_PRIVATE(subs);
uint8_t mode = field->mode;
if (UPB_UNLIKELY(mode & kUpb_LabelFlags_IsExtension)) {
@ -13340,7 +13366,7 @@ static const char* _upb_Decoder_DecodeMessage(upb_Decoder* d, const char* ptr,
}
}
return UPB_UNLIKELY(layout && layout->required_count)
return UPB_UNLIKELY(layout && layout->UPB_PRIVATE(required_count))
? _upb_Decoder_CheckRequired(d, ptr, msg, layout)
: ptr;
}
@ -13476,9 +13502,9 @@ static const char* fastdecode_dispatch(UPB_PARSE_PARAMS) {
switch (upb_EpsCopyInputStream_IsDoneStatus(&d->input, ptr, &overrun)) {
case kUpb_IsDoneStatus_Done:
*(uint32_t*)msg |= hasbits; // Sync hasbits.
const upb_MiniTable* l = decode_totablep(table);
return UPB_UNLIKELY(l->required_count)
? _upb_Decoder_CheckRequired(d, ptr, msg, l)
const upb_MiniTable* m = decode_totablep(table);
return UPB_UNLIKELY(m->UPB_PRIVATE(required_count))
? _upb_Decoder_CheckRequired(d, ptr, msg, m)
: ptr;
case kUpb_IsDoneStatus_NotDone:
break;
@ -14327,12 +14353,12 @@ static const char* fastdecode_tosubmsg(upb_EpsCopyInputStream* e,
upb_Message** dst; \
uint32_t submsg_idx = (data >> 16) & 0xff; \
const upb_MiniTable* tablep = decode_totablep(table); \
const upb_MiniTable* subtablep = \
upb_MiniTableSub_Message(tablep->subs[submsg_idx]); \
const upb_MiniTable* subtablep = upb_MiniTableSub_Message( \
*UPB_PRIVATE(_upb_MiniTable_GetSubByIndex)(tablep, submsg_idx)); \
fastdecode_submsgdata submsg = {decode_totable(subtablep)}; \
fastdecode_arr farr; \
\
if (subtablep->table_mask == (uint8_t)-1) { \
if (subtablep->UPB_PRIVATE(table_mask) == (uint8_t)-1) { \
d->depth++; \
RETURN_GENERIC("submessage doesn't have fast tables."); \
} \
@ -14597,7 +14623,7 @@ static void encode_TaggedMessagePtr(upb_encstate* e,
upb_TaggedMessagePtr tagged,
const upb_MiniTable* m, size_t* size) {
if (upb_TaggedMessagePtr_IsEmpty(tagged)) {
m = &_kUpb_MiniTable_Empty;
m = UPB_PRIVATE(_upb_MiniTable_Empty)();
}
encode_message(e, _upb_TaggedMessagePtr_GetMessage(tagged), m, size);
}
@ -14798,12 +14824,12 @@ static void encode_array(upb_encstate* e, const upb_Message* msg,
static void encode_mapentry(upb_encstate* e, uint32_t number,
const upb_MiniTable* layout,
const upb_MapEntry* ent) {
const upb_MiniTableField* key_field = &layout->fields[0];
const upb_MiniTableField* val_field = &layout->fields[1];
const upb_MiniTableField* key_field = &layout->UPB_PRIVATE(fields)[0];
const upb_MiniTableField* val_field = &layout->UPB_PRIVATE(fields)[1];
size_t pre_len = e->limit - e->ptr;
size_t size;
encode_scalar(e, &ent->data.v, layout->subs, val_field);
encode_scalar(e, &ent->data.k, layout->subs, key_field);
encode_scalar(e, &ent->data.v, layout->UPB_PRIVATE(subs), val_field);
encode_scalar(e, &ent->data.k, layout->UPB_PRIVATE(subs), key_field);
size = (e->limit - e->ptr) - pre_len;
encode_varint(e, size);
encode_tag(e, number, kUpb_WireType_Delimited);
@ -14815,15 +14841,15 @@ static void encode_map(upb_encstate* e, const upb_Message* msg,
const upb_Map* map = *UPB_PTR_AT(msg, f->offset, const upb_Map*);
const upb_MiniTable* layout =
upb_MiniTableSub_Message(subs[f->UPB_PRIVATE(submsg_index)]);
UPB_ASSERT(layout->field_count == 2);
UPB_ASSERT(layout->UPB_PRIVATE(field_count) == 2);
if (map == NULL) return;
if (e->options & kUpb_EncodeOption_Deterministic) {
_upb_sortedmap sorted;
_upb_mapsorter_pushmap(&e->sorter,
layout->fields[0].UPB_PRIVATE(descriptortype), map,
&sorted);
_upb_mapsorter_pushmap(
&e->sorter, layout->UPB_PRIVATE(fields)[0].UPB_PRIVATE(descriptortype),
map, &sorted);
upb_MapEntry ent;
while (_upb_sortedmap_next(&e->sorter, map, &sorted, &ent)) {
encode_mapentry(e, f->number, layout, &ent);
@ -14925,11 +14951,12 @@ static void encode_message(upb_encstate* e, const upb_Message* msg,
const upb_MiniTable* m, size_t* size) {
size_t pre_len = e->limit - e->ptr;
if ((e->options & kUpb_EncodeOption_CheckRequired) && m->required_count) {
if ((e->options & kUpb_EncodeOption_CheckRequired) &&
m->UPB_PRIVATE(required_count)) {
uint64_t msg_head;
memcpy(&msg_head, msg, 8);
msg_head = _upb_BigEndian_Swap64(msg_head);
if (upb_MiniTable_requiredmask(m) & ~msg_head) {
if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) {
encode_err(e, kUpb_EncodeStatus_MissingRequired);
}
}
@ -14943,7 +14970,7 @@ static void encode_message(upb_encstate* e, const upb_Message* msg,
}
}
if (m->ext != kUpb_ExtMode_NonExtendable) {
if (m->UPB_PRIVATE(ext) != kUpb_ExtMode_NonExtendable) {
/* Encode all extensions together. Unlike C++, we do not attempt to keep
* these in field number order relative to normal fields or even to each
* other. */
@ -14954,25 +14981,26 @@ static void encode_message(upb_encstate* e, const upb_Message* msg,
_upb_sortedmap sorted;
_upb_mapsorter_pushexts(&e->sorter, ext, ext_count, &sorted);
while (_upb_sortedmap_nextext(&e->sorter, &sorted, &ext)) {
encode_ext(e, ext, m->ext == kUpb_ExtMode_IsMessageSet);
encode_ext(e, ext, m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet);
}
_upb_mapsorter_popmap(&e->sorter, &sorted);
} else {
const upb_Message_Extension* end = ext + ext_count;
for (; ext != end; ext++) {
encode_ext(e, ext, m->ext == kUpb_ExtMode_IsMessageSet);
encode_ext(e, ext, m->UPB_PRIVATE(ext) == kUpb_ExtMode_IsMessageSet);
}
}
}
}
if (m->field_count) {
const upb_MiniTableField* f = &m->fields[m->field_count];
const upb_MiniTableField* first = &m->fields[0];
if (m->UPB_PRIVATE(field_count)) {
const upb_MiniTableField* f =
&m->UPB_PRIVATE(fields)[m->UPB_PRIVATE(field_count)];
const upb_MiniTableField* first = &m->UPB_PRIVATE(fields)[0];
while (f != first) {
f--;
if (encode_shouldencode(e, msg, m->subs, f)) {
encode_field(e, msg, m->subs, f);
if (encode_shouldencode(e, msg, m->UPB_PRIVATE(subs), f)) {
encode_field(e, msg, m->UPB_PRIVATE(subs), f);
}
}
}
@ -15113,3 +15141,4 @@ const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag,
#undef UPB_ATOMIC
#undef UPB_USE_C11_ATOMICS
#undef UPB_PRIVATE
#undef UPB_ONLYBITS

@ -182,6 +182,12 @@ Error, UINTPTR_MAX is undefined
#define UPB_PRIVATE(x) x##_dont_copy_me__upb_internal_use_only
#ifdef UPB_ALLOW_PRIVATE_ACCESS__FOR_BITS_ONLY
#define UPB_ONLYBITS(x) x
#else
#define UPB_ONLYBITS(x) UPB_PRIVATE(x)
#endif
/* Configure whether fasttable is switched on or not. *************************/
#ifdef __has_attribute
@ -1311,82 +1317,6 @@ upb_MiniTableField_Type(const upb_MiniTableField* f) {
#define UPB_MINI_TABLE_INTERNAL_MESSAGE_H_
// Must be last.
struct upb_Decoder;
typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr,
upb_Message* msg, intptr_t table,
uint64_t hasbits, uint64_t data);
typedef struct {
uint64_t field_data;
_upb_FieldParser* field_parser;
} _upb_FastTable_Entry;
typedef enum {
kUpb_ExtMode_NonExtendable = 0, // Non-extendable message.
kUpb_ExtMode_Extendable = 1, // Normal extendable message.
kUpb_ExtMode_IsMessageSet = 2, // MessageSet message.
kUpb_ExtMode_IsMessageSet_ITEM =
3, // MessageSet item (temporary only, see decode.c)
// During table building we steal a bit to indicate that the message is a map
// entry. *Only* used during table building!
kUpb_ExtMode_IsMapEntry = 4,
} upb_ExtMode;
// upb_MiniTable represents the memory layout of a given upb_MessageDef.
// The members are public so generated code can initialize them,
// but users MUST NOT directly read or write any of its members.
struct upb_MiniTable {
const union upb_MiniTableSub* subs;
const struct upb_MiniTableField* fields;
// Must be aligned to sizeof(void*). Doesn't include internal members like
// unknown fields, extension dict, pointer to msglayout, etc.
uint16_t size;
uint16_t field_count;
uint8_t ext; // upb_ExtMode, declared as uint8_t so sizeof(ext) == 1
uint8_t dense_below;
uint8_t table_mask;
uint8_t required_count; // Required fields have the lowest hasbits.
// To statically initialize the tables of variable length, we need a flexible
// array member, and we need to compile in gnu99 mode (constant initialization
// of flexible array members is a GNU extension, not in C99 unfortunately.
_upb_FastTable_Entry fasttable[];
};
#ifdef __cplusplus
extern "C" {
#endif
// A MiniTable for an empty message, used for unlinked sub-messages.
extern const struct upb_MiniTable _kUpb_MiniTable_Empty;
// Computes a bitmask in which the |l->required_count| lowest bits are set,
// except that we skip the lowest bit (because upb never uses hasbit 0).
//
// Sample output:
// requiredmask(1) => 0b10 (0x2)
// requiredmask(5) => 0b111110 (0x3e)
UPB_INLINE uint64_t upb_MiniTable_requiredmask(const struct upb_MiniTable* l) {
int n = l->required_count;
assert(0 < n && n <= 63);
return ((1ULL << n) - 1) << 1;
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */
#ifndef UPB_MINI_TABLE_SUB_H_
#define UPB_MINI_TABLE_SUB_H_
#ifndef UPB_MINI_TABLE_INTERNAL_SUB_H_
#define UPB_MINI_TABLE_INTERNAL_SUB_H_
@ -1434,34 +1364,117 @@ UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTableSub_Message)(
// Must be last.
typedef union upb_MiniTableSub upb_MiniTableSub;
struct upb_Decoder;
typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr,
upb_Message* msg, intptr_t table,
uint64_t hasbits, uint64_t data);
typedef struct {
uint64_t field_data;
_upb_FieldParser* field_parser;
} _upb_FastTable_Entry;
typedef enum {
kUpb_ExtMode_NonExtendable = 0, // Non-extendable message.
kUpb_ExtMode_Extendable = 1, // Normal extendable message.
kUpb_ExtMode_IsMessageSet = 2, // MessageSet message.
kUpb_ExtMode_IsMessageSet_ITEM =
3, // MessageSet item (temporary only, see decode.c)
// During table building we steal a bit to indicate that the message is a map
// entry. *Only* used during table building!
kUpb_ExtMode_IsMapEntry = 4,
} upb_ExtMode;
// upb_MiniTable represents the memory layout of a given upb_MessageDef.
// The members are public so generated code can initialize them,
// but users MUST NOT directly read or write any of its members.
struct upb_MiniTable {
const union upb_MiniTableSub* UPB_PRIVATE(subs);
const struct upb_MiniTableField* UPB_ONLYBITS(fields);
// Must be aligned to sizeof(void*). Doesn't include internal members like
// unknown fields, extension dict, pointer to msglayout, etc.
uint16_t size;
uint16_t UPB_ONLYBITS(field_count);
uint8_t UPB_PRIVATE(ext); // upb_ExtMode, uint8_t here so sizeof(ext) == 1
uint8_t UPB_PRIVATE(dense_below);
uint8_t UPB_PRIVATE(table_mask);
uint8_t UPB_PRIVATE(required_count); // Required fields have the low hasbits.
// To statically initialize the tables of variable length, we need a flexible
// array member, and we need to compile in gnu99 mode (constant initialization
// of flexible array members is a GNU extension, not in C99 unfortunately.
_upb_FastTable_Entry UPB_PRIVATE(fasttable)[];
};
#ifdef __cplusplus
extern "C" {
#endif
// Constructors
UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTable_Empty)(void) {
extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty);
UPB_API_INLINE upb_MiniTableSub
upb_MiniTableSub_FromEnum(const struct upb_MiniTableEnum* subenum) {
return UPB_PRIVATE(_upb_MiniTableSub_FromEnum)(subenum);
return &UPB_PRIVATE(_kUpb_MiniTable_Empty);
}
UPB_API_INLINE upb_MiniTableSub
upb_MiniTableSub_FromMessage(const struct upb_MiniTable* submsg) {
return UPB_PRIVATE(_upb_MiniTableSub_FromMessage)(submsg);
UPB_INLINE int UPB_PRIVATE(_upb_MiniTable_FieldCount)(
const struct upb_MiniTable* m) {
return m->UPB_ONLYBITS(field_count);
}
// Getters
UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_IsEmpty)(
const struct upb_MiniTable* m) {
extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty);
UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTableSub_Enum(
upb_MiniTableSub sub) {
return UPB_PRIVATE(_upb_MiniTableSub_Enum)(sub);
return m == &UPB_PRIVATE(_kUpb_MiniTable_Empty);
}
UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableSub_Message(
upb_MiniTableSub sub) {
return UPB_PRIVATE(_upb_MiniTableSub_Message)(sub);
UPB_INLINE const struct upb_MiniTableField* UPB_PRIVATE(
_upb_MiniTable_GetFieldByIndex)(const struct upb_MiniTable* m, uint32_t i) {
return &m->UPB_ONLYBITS(fields)[i];
}
UPB_INLINE const union upb_MiniTableSub* UPB_PRIVATE(
_upb_MiniTable_GetSubByIndex)(const struct upb_MiniTable* m, uint32_t i) {
return &m->UPB_PRIVATE(subs)[i];
}
UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(
_upb_MiniTable_GetSubMessageTable)(const struct upb_MiniTable* m,
const struct upb_MiniTableField* f) {
UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_CType)(f) == kUpb_CType_Message);
const struct upb_MiniTable* ret = UPB_PRIVATE(_upb_MiniTableSub_Message)(
m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]);
UPB_ASSUME(ret);
return UPB_PRIVATE(_upb_MiniTable_IsEmpty)(ret) ? NULL : ret;
}
UPB_INLINE const struct upb_MiniTableEnum* UPB_PRIVATE(
_upb_MiniTable_GetSubEnumTable)(const struct upb_MiniTable* m,
const struct upb_MiniTableField* f) {
UPB_ASSERT(UPB_PRIVATE(_upb_MiniTableField_CType)(f) == kUpb_CType_Enum);
return UPB_PRIVATE(_upb_MiniTableSub_Enum)(
m->UPB_PRIVATE(subs)[f->UPB_PRIVATE(submsg_index)]);
}
UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_MessageFieldIsLinked)(
const struct upb_MiniTable* m, const struct upb_MiniTableField* f) {
return UPB_PRIVATE(_upb_MiniTable_GetSubMessageTable)(m, f) != NULL;
}
// Computes a bitmask in which the |m->required_count| lowest bits are set,
// except that we skip the lowest bit (because upb never uses hasbit 0).
//
// Sample output:
// RequiredMask(1) => 0b10 (0x2)
// RequiredMask(5) => 0b111110 (0x3e)
UPB_INLINE uint64_t
UPB_PRIVATE(_upb_MiniTable_RequiredMask)(const struct upb_MiniTable* m) {
int n = m->UPB_PRIVATE(required_count);
UPB_ASSERT(0 < n && n <= 63);
return ((1ULL << n) - 1) << 1;
}
#ifdef __cplusplus
@ -1469,50 +1482,54 @@ UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableSub_Message(
#endif
#endif /* UPB_MINI_TABLE_SUB_H_ */
#endif /* UPB_MINI_TABLE_INTERNAL_MESSAGE_H_ */
// Must be last.
typedef struct upb_MiniTable upb_MiniTable;
#ifdef __cplusplus
extern "C" {
#endif
typedef struct upb_MiniTable upb_MiniTable;
UPB_API const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
const upb_MiniTable* table, uint32_t number);
const upb_MiniTable* m, uint32_t number);
UPB_API_INLINE const upb_MiniTableField* upb_MiniTable_GetFieldByIndex(
const upb_MiniTable* t, uint32_t index) {
return &t->fields[index];
const upb_MiniTable* m, uint32_t index) {
return UPB_PRIVATE(_upb_MiniTable_GetFieldByIndex)(m, index);
}
UPB_API_INLINE int upb_MiniTable_FieldCount(const upb_MiniTable* m) {
return UPB_PRIVATE(_upb_MiniTable_FieldCount)(m);
}
// Returns the MiniTable for this message field. If the field is unlinked,
// returns NULL.
// Returns the MiniTable for a message field, NULL if the field is unlinked.
UPB_API_INLINE const upb_MiniTable* upb_MiniTable_GetSubMessageTable(
const upb_MiniTable* mini_table, const upb_MiniTableField* field) {
UPB_ASSERT(upb_MiniTableField_CType(field) == kUpb_CType_Message);
const upb_MiniTable* ret = upb_MiniTableSub_Message(
mini_table->subs[field->UPB_PRIVATE(submsg_index)]);
UPB_ASSUME(ret);
return ret == &_kUpb_MiniTable_Empty ? NULL : ret;
const upb_MiniTable* m, const upb_MiniTableField* f) {
return UPB_PRIVATE(_upb_MiniTable_GetSubMessageTable)(m, f);
}
// Returns the MiniTableEnum for this enum field. If the field is unlinked,
// returns NULL.
// Returns the MiniTableEnum for a message field, NULL if the field is unlinked.
UPB_API_INLINE const upb_MiniTableEnum* upb_MiniTable_GetSubEnumTable(
const upb_MiniTable* mini_table, const upb_MiniTableField* f) {
UPB_ASSERT(upb_MiniTableField_CType(f) == kUpb_CType_Enum);
return upb_MiniTableSub_Enum(mini_table->subs[f->UPB_PRIVATE(submsg_index)]);
const upb_MiniTable* m, const upb_MiniTableField* f) {
return UPB_PRIVATE(_upb_MiniTable_GetSubEnumTable)(m, f);
}
// Returns true if this MiniTable field is linked to a MiniTable for the
// sub-message.
UPB_API_INLINE bool upb_MiniTable_MessageFieldIsLinked(
const upb_MiniTable* mini_table, const upb_MiniTableField* field) {
return upb_MiniTable_GetSubMessageTable(mini_table, field) != NULL;
const upb_MiniTable* m, const upb_MiniTableField* f) {
return UPB_PRIVATE(_upb_MiniTable_MessageFieldIsLinked)(m, f);
}
// TODO: Implement convenience getters for map entries:
//
// upb_MiniTable_GetMapKey()
// upb_MiniTable_GetMapValue()
// These could also assert that this is indeed a map entry (well, as best we
// can. We can assert that there are two fields with field numbers 1 and 2).
// If this field is in a oneof, returns the first field in the oneof.
//
// Otherwise returns NULL.
@ -2402,8 +2419,8 @@ struct upb_Message_InternalData {
/* Maps upb_CType -> memory size. */
extern char _upb_CTypeo_size[12];
UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* t) {
return t->size + sizeof(upb_Message_Internal);
UPB_INLINE size_t upb_msg_sizeof(const upb_MiniTable* m) {
return m->size + sizeof(upb_Message_Internal);
}
// Inline version upb_Message_New(), for internal use.
@ -2899,6 +2916,49 @@ UPB_INLINE void UPB_PRIVATE(_upb_Array_Set)(upb_Array* array, size_t i,
#endif /* UPB_MESSAGE_INTERNAL_ARRAY_H_ */
#ifndef UPB_MINI_TABLE_SUB_H_
#define UPB_MINI_TABLE_SUB_H_
// Must be last.
typedef union upb_MiniTableSub upb_MiniTableSub;
#ifdef __cplusplus
extern "C" {
#endif
// Constructors
UPB_API_INLINE upb_MiniTableSub
upb_MiniTableSub_FromEnum(const struct upb_MiniTableEnum* subenum) {
return UPB_PRIVATE(_upb_MiniTableSub_FromEnum)(subenum);
}
UPB_API_INLINE upb_MiniTableSub
upb_MiniTableSub_FromMessage(const struct upb_MiniTable* submsg) {
return UPB_PRIVATE(_upb_MiniTableSub_FromMessage)(submsg);
}
// Getters
UPB_API_INLINE const struct upb_MiniTableEnum* upb_MiniTableSub_Enum(
upb_MiniTableSub sub) {
return UPB_PRIVATE(_upb_MiniTableSub_Enum)(sub);
}
UPB_API_INLINE const struct upb_MiniTable* upb_MiniTableSub_Message(
upb_MiniTableSub sub) {
return UPB_PRIVATE(_upb_MiniTableSub_Message)(sub);
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* UPB_MINI_TABLE_SUB_H_ */
// Must be last.
#ifdef __cplusplus
@ -3214,7 +3274,7 @@ UPB_API_INLINE void _upb_Message_SetTaggedMessagePtr(
UPB_SIZE(kUpb_FieldRep_4Byte, kUpb_FieldRep_8Byte));
UPB_ASSUME(upb_MiniTableField_IsScalar(field));
UPB_ASSERT(upb_MiniTableSub_Message(
mini_table->subs[field->UPB_PRIVATE(submsg_index)]));
mini_table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]));
_upb_Message_SetNonExtensionField(msg, field, &sub_message);
}
@ -3234,7 +3294,7 @@ UPB_API_INLINE upb_Message* upb_Message_GetOrCreateMutableMessage(
upb_Message* sub_message = *UPB_PTR_AT(msg, field->offset, upb_Message*);
if (!sub_message) {
const upb_MiniTable* sub_mini_table = upb_MiniTableSub_Message(
mini_table->subs[field->UPB_PRIVATE(submsg_index)]);
mini_table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]);
UPB_ASSERT(sub_mini_table);
sub_message = _upb_Message_New(sub_mini_table, arena);
*UPB_PTR_AT(msg, field->offset, upb_Message*) = sub_message;
@ -3304,9 +3364,9 @@ UPB_API_INLINE upb_Map* upb_Message_GetOrCreateMutableMap(
const upb_MiniTableField* field, upb_Arena* arena) {
UPB_ASSUME(upb_MiniTableField_CType(field) == kUpb_CType_Message);
const upb_MiniTableField* map_entry_key_field =
&map_entry_mini_table->fields[0];
&map_entry_mini_table->UPB_PRIVATE(fields)[0];
const upb_MiniTableField* map_entry_value_field =
&map_entry_mini_table->fields[1];
&map_entry_mini_table->UPB_PRIVATE(fields)[1];
return _upb_Message_GetOrCreateMutableMap(
msg, field,
_upb_Map_CTypeSize(upb_MiniTableField_CType(map_entry_key_field)),
@ -13239,12 +13299,12 @@ non_ascii:
const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr,
const upb_Message* msg,
const upb_MiniTable* l);
const upb_MiniTable* m);
/* x86-64 pointers always have the high 16 bits matching. So we can shift
* left 8 and right 8 without loss of information. */
UPB_INLINE intptr_t decode_totable(const upb_MiniTable* tablep) {
return ((intptr_t)tablep << 8) | tablep->table_mask;
return ((intptr_t)tablep << 8) | tablep->UPB_PRIVATE(table_mask);
}
UPB_INLINE const upb_MiniTable* decode_totablep(intptr_t table) {
@ -13285,9 +13345,9 @@ const char* _upb_FastDecoder_TagDispatch(upb_Decoder* d, const char* ptr,
size_t idx = tag & mask;
UPB_ASSUME((idx & 7) == 0);
idx >>= 3;
data = table_p->fasttable[idx].field_data ^ tag;
UPB_MUSTTAIL return table_p->fasttable[idx].field_parser(d, ptr, msg, table,
hasbits, data);
data = table_p->UPB_PRIVATE(fasttable)[idx].field_data ^ tag;
UPB_MUSTTAIL return table_p->UPB_PRIVATE(fasttable)[idx].field_parser(
d, ptr, msg, table, hasbits, data);
}
#endif
@ -13597,3 +13657,4 @@ UPB_INLINE const char* upb_WireReader_SkipValue(
#undef UPB_ATOMIC
#undef UPB_USE_C11_ATOMICS
#undef UPB_PRIVATE
#undef UPB_ONLYBITS

Loading…
Cancel
Save