upb: lock down upb_MiniTable (mostly)

PiperOrigin-RevId: 586542236
pull/14843/head
Eric Salo 1 year ago committed by Copybara-Service
parent dbcc46febd
commit bb5322a194
  1. 1
      upb/message/BUILD
  2. 10
      upb/message/accessors.c
  3. 8
      upb/message/accessors.h
  4. 4
      upb/message/accessors_test.cc
  5. 21
      upb/message/copy.c
  6. 4
      upb/message/internal/message.h
  7. 4
      upb/message/promote.c
  8. 31
      upb/message/promote_test.cc
  9. 1
      upb/mini_descriptor/BUILD
  10. 74
      upb/mini_descriptor/decode.c
  11. 46
      upb/mini_descriptor/internal/encode_test.cc
  12. 39
      upb/mini_descriptor/link.c
  13. 6
      upb/mini_table/compat.c
  14. 22
      upb/mini_table/internal/message.c
  15. 84
      upb/mini_table/internal/message.h
  16. 24
      upb/mini_table/message.c
  17. 46
      upb/mini_table/message.h
  18. 6
      upb/port/def.inc
  19. 1
      upb/port/undef.inc
  20. 2
      upb/reflection/field_def.c
  21. 11
      upb/reflection/message_def.c
  22. 4
      upb/test/fuzz_util.cc
  23. 66
      upb/wire/decode.c
  24. 12
      upb/wire/decode_fast.c
  25. 40
      upb/wire/encode.c
  26. 10
      upb/wire/internal/decode.h
  27. 22
      upb_generator/protoc-gen-upb_minitable.cc

@ -344,7 +344,6 @@ cc_test(
"//upb:mini_descriptor",
"//upb:mini_descriptor_internal",
"//upb:mini_table",
"//upb:port",
"//upb:wire",
"//upb/test:test_messages_proto2_upb_proto",
"//upb/test:test_messages_proto3_upb_proto",

@ -27,14 +27,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;

@ -347,7 +347,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);
}
@ -367,7 +367,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;
@ -437,9 +437,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)),

@ -394,7 +394,7 @@ TEST(GeneratedCode, EnumClosedCheck) {
upb_MiniTable* table =
upb_MiniTable_Build(e.data().data(), e.data().size(), arena, &status);
const upb_MiniTableField* enumField = &table->fields[1];
const upb_MiniTableField* enumField = &table->UPB_PRIVATE(fields)[1];
EXPECT_EQ(upb_MiniTableField_Type(enumField), kUpb_FieldType_Enum);
EXPECT_FALSE(upb_MiniTableField_IsClosedEnum(enumField));
@ -407,7 +407,7 @@ TEST(GeneratedCode, EnumClosedCheck) {
table =
upb_MiniTable_Build(e2.data().data(), e2.data().size(), arena, &status);
const upb_MiniTableField* closedEnumField = &table->fields[1];
const upb_MiniTableField* closedEnumField = &table->UPB_PRIVATE(fields)[1];
EXPECT_EQ(upb_MiniTableField_Type(closedEnumField), kUpb_FieldType_Enum);
EXPECT_TRUE(upb_MiniTableField_IsClosedEnum(closedEnumField));
upb_Arena_Free(arena);

@ -74,7 +74,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);
@ -97,7 +97,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)
@ -120,12 +121,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),
@ -193,8 +196,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: {
@ -208,7 +211,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);

@ -68,8 +68,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.

@ -327,10 +327,10 @@ upb_UnknownToMessage_Status upb_MiniTable_PromoteUnknownToMap(
const upb_MiniTableField* field, int decode_options, 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[field->UPB_PRIVATE(submsg_index)]);
mini_table->UPB_PRIVATE(subs)[field->UPB_PRIVATE(submsg_index)]);
UPB_ASSERT(map_entry_mini_table);
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);
UPB_ASSERT(upb_MiniTableField_IsMap(field));
// Find all unknowns with given field number and parse.
upb_FindUnknownRet unknown;

@ -46,9 +46,6 @@
#include "upb/wire/decode.h"
#include "upb/wire/encode.h"
// Must be last
#include "upb/port/def.inc"
namespace {
TEST(GeneratedCode, FindUnknown) {
@ -715,17 +712,18 @@ TEST(GeneratedCode, PromoteUnknownMessageOld) {
EXPECT_EQ(unknown.status, kUpb_FindUnknown_Ok);
// Update mini table and promote unknown to a message.
EXPECT_TRUE(upb_MiniTable_SetSubMessage(
mini_table, (upb_MiniTableField*)&mini_table->fields[1],
mini_table,
(upb_MiniTableField*)upb_MiniTable_GetFieldByIndex(mini_table, 1),
&upb_0test__ModelWithExtensions_msg_init));
const int decode_options =
upb_DecodeOptions_MaxDepth(0); // UPB_DECODE_ALIAS disabled.
upb_UnknownToMessageRet promote_result =
upb_MiniTable_PromoteUnknownToMessage(
msg, mini_table, &mini_table->fields[1],
msg, mini_table, upb_MiniTable_GetFieldByIndex(mini_table, 1),
&upb_0test__ModelWithExtensions_msg_init, decode_options, arena);
EXPECT_EQ(promote_result.status, kUpb_UnknownToMessage_Ok);
const upb_Message* promoted_message =
upb_Message_GetMessage(msg, &mini_table->fields[1], nullptr);
const upb_Message* promoted_message = upb_Message_GetMessage(
msg, upb_MiniTable_GetFieldByIndex(mini_table, 1), nullptr);
EXPECT_EQ(upb_test_ModelWithExtensions_random_int32(
(upb_test_ModelWithExtensions*)promoted_message),
12);
@ -764,17 +762,19 @@ TEST(GeneratedCode, PromoteUnknownRepeatedMessageOld) {
// Update mini table and promote unknown to a message.
EXPECT_TRUE(upb_MiniTable_SetSubMessage(
mini_table, (upb_MiniTableField*)&mini_table->fields[2],
mini_table,
(upb_MiniTableField*)upb_MiniTable_GetFieldByIndex(mini_table, 2),
&upb_0test__ModelWithExtensions_msg_init));
const int decode_options =
upb_DecodeOptions_MaxDepth(0); // UPB_DECODE_ALIAS disabled.
upb_UnknownToMessage_Status promote_result =
upb_MiniTable_PromoteUnknownToMessageArray(
msg, &mini_table->fields[2], &upb_0test__ModelWithExtensions_msg_init,
decode_options, arena);
msg, upb_MiniTable_GetFieldByIndex(mini_table, 2),
&upb_0test__ModelWithExtensions_msg_init, decode_options, arena);
EXPECT_EQ(promote_result, kUpb_UnknownToMessage_Ok);
upb_Array* array = upb_Message_GetMutableArray(msg, &mini_table->fields[2]);
upb_Array* array = upb_Message_GetMutableArray(
msg, upb_MiniTable_GetFieldByIndex(mini_table, 2));
const upb_Message* promoted_message = upb_Array_Get(array, 0).msg_val;
EXPECT_EQ(upb_test_ModelWithExtensions_random_int32(
(upb_test_ModelWithExtensions*)promoted_message),
@ -822,15 +822,18 @@ TEST(GeneratedCode, PromoteUnknownToMapOld) {
// Update mini table and promote unknown to a message.
EXPECT_TRUE(upb_MiniTable_SetSubMessage(
mini_table, (upb_MiniTableField*)&mini_table->fields[1],
mini_table,
(upb_MiniTableField*)upb_MiniTable_GetFieldByIndex(mini_table, 1),
map_entry_mini_table));
upb_UnknownToMessage_Status promote_result =
upb_MiniTable_PromoteUnknownToMap(msg, mini_table, &mini_table->fields[1],
upb_MiniTable_PromoteUnknownToMap(
msg, mini_table, upb_MiniTable_GetFieldByIndex(mini_table, 1),
decode_options, arena);
EXPECT_EQ(promote_result, kUpb_UnknownToMessage_Ok);
upb_Map* map = upb_Message_GetOrCreateMutableMap(
msg, map_entry_mini_table, &mini_table->fields[1], arena);
msg, map_entry_mini_table, upb_MiniTable_GetFieldByIndex(mini_table, 1),
arena);
EXPECT_NE(map, nullptr);
// Lookup in map.
upb_MessageValue key;

@ -66,6 +66,7 @@ cc_test(
"//upb:message_accessors_internal",
"//upb:mini_table",
"//upb:mini_table_internal",
"//upb:port",
"//upb:wire",
"@com_google_absl//absl/container:flat_hash_set",
],

@ -389,16 +389,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;
@ -408,7 +408,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,
@ -439,7 +439,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) {
@ -449,7 +449,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;
@ -464,7 +464,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;
@ -478,14 +478,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);
}
@ -512,7 +512,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;
@ -536,27 +536,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;
}
@ -595,7 +597,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];
}
}
@ -663,9 +665,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();
}
@ -676,8 +678,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.
@ -689,7 +691,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,
@ -701,11 +703,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(
@ -714,11 +716,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;
@ -811,7 +813,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;

@ -34,6 +34,9 @@
// #include "testing/fuzzing/fuzztest.h"
// end:google_only
// Must be last.
#include "upb/port/def.inc"
namespace protobuf = ::google::protobuf;
class MiniTableTest : public testing::TestWithParam<upb_MiniTablePlatform> {};
@ -44,8 +47,8 @@ TEST_P(MiniTableTest, Empty) {
upb_MiniTable* table =
_upb_MiniTable_Build(nullptr, 0, GetParam(), arena.ptr(), status.ptr());
ASSERT_NE(nullptr, table);
EXPECT_EQ(0, table->field_count);
EXPECT_EQ(0, table->required_count);
EXPECT_EQ(0, table->UPB_PRIVATE(field_count));
EXPECT_EQ(0, table->UPB_PRIVATE(required_count));
}
TEST_P(MiniTableTest, AllScalarTypes) {
@ -61,16 +64,16 @@ TEST_P(MiniTableTest, AllScalarTypes) {
upb_MiniTable* table = _upb_MiniTable_Build(
e.data().data(), e.data().size(), GetParam(), arena.ptr(), status.ptr());
ASSERT_NE(nullptr, table);
EXPECT_EQ(count, table->field_count);
EXPECT_EQ(count, table->UPB_PRIVATE(field_count));
absl::flat_hash_set<size_t> offsets;
for (int i = 0; i < 16; i++) {
const upb_MiniTableField* f = &table->fields[i];
const upb_MiniTableField* f = &table->UPB_PRIVATE(fields)[i];
EXPECT_EQ(i + 1, f->number);
EXPECT_TRUE(upb_MiniTableField_IsScalar(f));
EXPECT_TRUE(offsets.insert(f->offset).second);
EXPECT_TRUE(f->offset < table->size);
}
EXPECT_EQ(0, table->required_count);
EXPECT_EQ(0, table->UPB_PRIVATE(required_count));
}
TEST_P(MiniTableTest, AllRepeatedTypes) {
@ -87,16 +90,16 @@ TEST_P(MiniTableTest, AllRepeatedTypes) {
upb_MiniTable* table = _upb_MiniTable_Build(
e.data().data(), e.data().size(), GetParam(), arena.ptr(), status.ptr());
ASSERT_NE(nullptr, table);
EXPECT_EQ(count, table->field_count);
EXPECT_EQ(count, table->UPB_PRIVATE(field_count));
absl::flat_hash_set<size_t> offsets;
for (int i = 0; i < 16; i++) {
const upb_MiniTableField* f = &table->fields[i];
const upb_MiniTableField* f = &table->UPB_PRIVATE(fields)[i];
EXPECT_EQ(i + 1, f->number);
EXPECT_TRUE(upb_MiniTableField_IsArray(f));
EXPECT_TRUE(offsets.insert(f->offset).second);
EXPECT_TRUE(f->offset < table->size);
}
EXPECT_EQ(0, table->required_count);
EXPECT_EQ(0, table->UPB_PRIVATE(required_count));
}
TEST_P(MiniTableTest, Skips) {
@ -115,17 +118,17 @@ TEST_P(MiniTableTest, Skips) {
upb_MiniTable* table = _upb_MiniTable_Build(
e.data().data(), e.data().size(), GetParam(), arena.ptr(), status.ptr());
ASSERT_NE(nullptr, table);
EXPECT_EQ(count, table->field_count);
EXPECT_EQ(count, table->UPB_PRIVATE(field_count));
absl::flat_hash_set<size_t> offsets;
for (size_t i = 0; i < field_numbers.size(); i++) {
const upb_MiniTableField* f = &table->fields[i];
const upb_MiniTableField* f = &table->UPB_PRIVATE(fields)[i];
EXPECT_EQ(field_numbers[i], f->number);
EXPECT_EQ(kUpb_FieldType_Float, upb_MiniTableField_Type(f));
EXPECT_TRUE(upb_MiniTableField_IsScalar(f));
EXPECT_TRUE(offsets.insert(f->offset).second);
EXPECT_TRUE(f->offset < table->size);
}
EXPECT_EQ(0, table->required_count);
EXPECT_EQ(0, table->UPB_PRIVATE(required_count));
}
TEST_P(MiniTableTest, AllScalarTypesOneof) {
@ -145,22 +148,22 @@ TEST_P(MiniTableTest, AllScalarTypesOneof) {
upb_MiniTable* table = _upb_MiniTable_Build(
e.data().data(), e.data().size(), GetParam(), arena.ptr(), status.ptr());
ASSERT_NE(nullptr, table) << status.error_message();
EXPECT_EQ(count, table->field_count);
EXPECT_EQ(count, table->UPB_PRIVATE(field_count));
absl::flat_hash_set<size_t> offsets;
for (int i = 0; i < 16; i++) {
const upb_MiniTableField* f = &table->fields[i];
const upb_MiniTableField* f = &table->UPB_PRIVATE(fields)[i];
EXPECT_EQ(i + 1, f->number);
EXPECT_TRUE(upb_MiniTableField_IsScalar(f));
// For a oneof all fields have the same offset.
EXPECT_EQ(table->fields[0].offset, f->offset);
EXPECT_EQ(table->UPB_PRIVATE(fields)[0].offset, f->offset);
// All presence fields should point to the same oneof case offset.
size_t case_ofs = _upb_MiniTableField_OneofOffset(f);
EXPECT_EQ(table->fields[0].presence, f->presence);
EXPECT_EQ(table->UPB_PRIVATE(fields)[0].presence, f->presence);
EXPECT_TRUE(f->offset < table->size);
EXPECT_TRUE(case_ofs < table->size);
EXPECT_TRUE(case_ofs != f->offset);
}
EXPECT_EQ(0, table->required_count);
EXPECT_EQ(0, table->UPB_PRIVATE(required_count));
}
TEST_P(MiniTableTest, SizeOverflow) {
@ -240,9 +243,11 @@ TEST_P(MiniTableTest, SubsInitializedToEmpty) {
upb_MiniTable* table = _upb_MiniTable_Build(
e.data().data(), e.data().size(), GetParam(), arena.ptr(), status.ptr());
ASSERT_NE(nullptr, table);
EXPECT_EQ(table->field_count, 2);
EXPECT_EQ(upb_MiniTableSub_Message(table->subs[0]), &_kUpb_MiniTable_Empty);
EXPECT_EQ(upb_MiniTableSub_Message(table->subs[1]), &_kUpb_MiniTable_Empty);
EXPECT_EQ(table->UPB_PRIVATE(field_count), 2);
EXPECT_TRUE(UPB_PRIVATE(_upb_MiniTable_IsEmpty)(
upb_MiniTableSub_Message(table->UPB_PRIVATE(subs)[0])));
EXPECT_TRUE(UPB_PRIVATE(_upb_MiniTable_IsEmpty)(
upb_MiniTableSub_Message(table->UPB_PRIVATE(subs)[1])));
}
TEST(MiniTableEnumTest, PositiveAndNegative) {
@ -282,7 +287,8 @@ TEST_P(MiniTableTest, Extendible) {
upb_MiniTable* table = _upb_MiniTable_Build(
e.data().data(), e.data().size(), GetParam(), arena.ptr(), status.ptr());
ASSERT_NE(nullptr, table);
EXPECT_EQ(kUpb_ExtMode_Extendable, table->ext & kUpb_ExtMode_Extendable);
EXPECT_EQ(kUpb_ExtMode_Extendable,
table->UPB_PRIVATE(ext) & kUpb_ExtMode_Extendable);
}
// begin:google_only

@ -24,17 +24,18 @@
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;
@ -50,23 +51,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;
}
@ -76,8 +77,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;
@ -85,8 +86,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;
@ -107,8 +108,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;
@ -118,8 +119,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;

@ -29,11 +29,11 @@ static upb_MiniTableEquals_Status upb_deep_check(const upb_MiniTable* src,
const upb_MiniTable* dst,
upb_inttable* table,
upb_Arena** arena) {
if (src->field_count != dst->field_count)
if (src->UPB_PRIVATE(field_count) != dst->UPB_PRIVATE(field_count))
return kUpb_MiniTableEquals_NotEqual;
bool marked_src = false;
for (int i = 0; i < src->field_count; i++) {
const upb_MiniTableField* src_field = &src->fields[i];
for (int i = 0; i < upb_MiniTable_FieldCount(src); i++) {
const upb_MiniTableField* src_field = upb_MiniTable_GetFieldByIndex(src, i);
const upb_MiniTableField* dst_field =
upb_MiniTable_FindFieldByNumber(dst, src_field->number);

@ -7,13 +7,19 @@
#include "upb/mini_table/internal/message.h"
const struct upb_MiniTable _kUpb_MiniTable_Empty = {
.subs = NULL,
.fields = NULL,
#include <stddef.h>
// Must be last.
#include "upb/port/def.inc"
// 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,
};

@ -9,6 +9,8 @@
#define UPB_MINI_TABLE_INTERNAL_MESSAGE_H_
#include "upb/message/types.h"
#include "upb/mini_table/internal/field.h"
#include "upb/mini_table/internal/sub.h"
// Must be last.
#include "upb/port/def.inc"
@ -38,41 +40,91 @@ typedef enum {
// 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;
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 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.
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 fasttable[];
_upb_FastTable_Entry UPB_PRIVATE(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;
UPB_INLINE const struct upb_MiniTable* UPB_PRIVATE(_upb_MiniTable_Empty)(void) {
extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty);
return &UPB_PRIVATE(_kUpb_MiniTable_Empty);
}
UPB_INLINE int UPB_PRIVATE(_upb_MiniTable_FieldCount)(
const struct upb_MiniTable* m) {
return m->UPB_ONLYBITS(field_count);
}
UPB_INLINE bool UPB_PRIVATE(_upb_MiniTable_IsEmpty)(
const struct upb_MiniTable* m) {
extern const struct upb_MiniTable UPB_PRIVATE(_kUpb_MiniTable_Empty);
return m == &UPB_PRIVATE(_kUpb_MiniTable_Empty);
}
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 |l->required_count| lowest bits are set,
// 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_MiniTable_requiredmask(const struct upb_MiniTable* l) {
int n = l->required_count;
assert(0 < n && n <= 63);
// 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;
}

@ -18,21 +18,21 @@
#include "upb/port/def.inc"
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;
@ -41,7 +41,7 @@ const upb_MiniTableField* upb_MiniTable_FindFieldByNumber(
hi = mid - 1;
continue;
}
return &t->fields[mid];
return &m->UPB_PRIVATE(fields)[mid];
}
return NULL;
}
@ -51,8 +51,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;
@ -64,7 +65,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;

@ -11,51 +11,55 @@
#include "upb/mini_table/enum.h"
#include "upb/mini_table/field.h"
#include "upb/mini_table/internal/message.h"
#include "upb/mini_table/sub.h"
#include "upb/mini_table/internal/sub.h"
// Must be last.
#include "upb/port/def.inc"
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);
}
// Returns the MiniTable for this message field. If the field is unlinked,
// returns NULL.
UPB_API_INLINE int upb_MiniTable_FieldCount(const upb_MiniTable* m) {
return UPB_PRIVATE(_upb_MiniTable_FieldCount)(m);
}
// 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.

@ -185,6 +185,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

@ -54,3 +54,4 @@
#undef UPB_ATOMIC
#undef UPB_USE_C11_ATOMICS
#undef UPB_PRIVATE
#undef UPB_ONLYBITS

@ -233,7 +233,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];
}
}

@ -446,7 +446,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.
@ -482,9 +482,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);
@ -504,8 +504,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) ==

@ -143,9 +143,9 @@ bool Builder::LinkMessages() {
for (auto* t : mini_tables_) {
upb_MiniTable* table = const_cast<upb_MiniTable*>(t);
// For each field that requires a sub-table, assign one as appropriate.
for (size_t i = 0; i < table->field_count; i++) {
for (size_t i = 0; i < table->UPB_PRIVATE(field_count); i++) {
upb_MiniTableField* field =
const_cast<upb_MiniTableField*>(&table->fields[i]);
const_cast<upb_MiniTableField*>(&table->UPB_PRIVATE(fields)[i]);
if (link_ == input_->links.size()) link_ = 0;
if (upb_MiniTableField_CType(field) == kUpb_CType_Message &&
!upb_MiniTable_SetSubMessage(table, field, NextMiniTable())) {

@ -91,6 +91,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.
@ -249,7 +251,7 @@ static upb_Message* _upb_Decoder_NewSubMessage(upb_Decoder* d,
// 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));
@ -268,7 +270,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);
}
@ -592,8 +595,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));
@ -615,9 +618,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);
@ -627,11 +630,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);
}
@ -732,15 +738,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;
@ -749,11 +755,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;
}
@ -909,30 +915,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);
@ -952,9 +958,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) {
@ -991,9 +997,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
@ -1004,7 +1010,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));
}
@ -1132,7 +1138,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)) {
@ -1286,7 +1292,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;
}

@ -64,9 +64,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;
@ -915,12 +915,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."); \
} \

@ -216,7 +216,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);
}
@ -417,12 +417,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);
@ -434,15 +434,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);
@ -544,11 +544,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);
}
}
@ -562,7 +563,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. */
@ -573,25 +574,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);
}
}
}

@ -80,12 +80,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) {
@ -126,9 +126,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

@ -410,8 +410,8 @@ void WriteMessage(upb::MessageDefPtr message, const DefPoolPair& pools,
const upb_MiniTable* mt_64 = pools.GetMiniTable64(message);
std::map<int, std::string> subs;
for (int i = 0; i < mt_64->field_count; i++) {
const upb_MiniTableField* f = &mt_64->fields[i];
for (int i = 0; i < mt_64->UPB_PRIVATE(field_count); i++) {
const upb_MiniTableField* f = &mt_64->UPB_PRIVATE(fields)[i];
uint32_t index = f->UPB_PRIVATE(submsg_index);
if (index != kUpb_NoSub) {
auto pair =
@ -435,14 +435,16 @@ void WriteMessage(upb::MessageDefPtr message, const DefPoolPair& pools,
output("};\n\n");
}
if (mt_64->field_count > 0) {
if (mt_64->UPB_PRIVATE(field_count) > 0) {
std::string fields_array_name = msg_name + "__fields";
fields_array_ref = "&" + fields_array_name + "[0]";
output("static const upb_MiniTableField $0[$1] = {\n", fields_array_name,
mt_64->field_count);
for (int i = 0; i < mt_64->field_count; i++) {
WriteMessageField(message.FindFieldByNumber(mt_64->fields[i].number),
&mt_64->fields[i], &mt_32->fields[i], output);
mt_64->UPB_PRIVATE(field_count));
for (int i = 0; i < mt_64->UPB_PRIVATE(field_count); i++) {
WriteMessageField(
message.FindFieldByNumber(mt_64->UPB_PRIVATE(fields)[i].number),
&mt_64->UPB_PRIVATE(fields)[i], &mt_32->UPB_PRIVATE(fields)[i],
output);
}
output("};\n\n");
}
@ -471,8 +473,10 @@ void WriteMessage(upb::MessageDefPtr message, const DefPoolPair& pools,
output(" $0,\n", submsgs_array_ref);
output(" $0,\n", fields_array_ref);
output(" $0, $1, $2, $3, UPB_FASTTABLE_MASK($4), $5,\n",
ArchDependentSize(mt_32->size, mt_64->size), mt_64->field_count,
msgext, mt_64->dense_below, table_mask, mt_64->required_count);
ArchDependentSize(mt_32->size, mt_64->size),
mt_64->UPB_PRIVATE(field_count), msgext,
mt_64->UPB_PRIVATE(dense_below), table_mask,
mt_64->UPB_PRIVATE(required_count));
if (!table.empty()) {
output(" UPB_FASTTABLE_INIT({\n");
for (const auto& ent : table) {

Loading…
Cancel
Save