Passes nearly all tests!

pull/13171/head
Joshua Haberman 3 years ago
parent 21e9cc80de
commit 911a25e738
  1. 34
      cmake/google/protobuf/descriptor.upb.c
  2. 66
      upb/mini_table.c
  3. 29
      upb/mini_table.h
  4. 5
      upb/upb.h
  5. 19
      upbc/protoc-gen-upb.cc

@ -127,7 +127,9 @@ const upb_MiniTable google_protobuf_ExtensionRangeOptions_msginit = {
UPB_SIZE(4, 8), 1, kUpb_ExtMode_Extendable, 0, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_FieldDescriptorProto_submsgs[1] = {
static const upb_MiniTable_Sub google_protobuf_FieldDescriptorProto_submsgs[3] = {
{.subenum = &google_protobuf_FieldDescriptorProto_Label_enuminit},
{.subenum = &google_protobuf_FieldDescriptorProto_Type_enuminit},
{.submsg = &google_protobuf_FieldOptions_msginit},
};
@ -135,11 +137,11 @@ static const upb_MiniTable_Field google_protobuf_FieldDescriptorProto__fields[11
{1, UPB_SIZE(24, 24), UPB_SIZE(1, 1), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{2, UPB_SIZE(32, 40), UPB_SIZE(2, 2), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{3, UPB_SIZE(4, 4), UPB_SIZE(3, 3), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{4, UPB_SIZE(8, 8), UPB_SIZE(4, 4), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{5, UPB_SIZE(12, 12), UPB_SIZE(5, 5), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{4, UPB_SIZE(8, 8), UPB_SIZE(4, 4), 0, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{5, UPB_SIZE(12, 12), UPB_SIZE(5, 5), 1, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{6, UPB_SIZE(40, 56), UPB_SIZE(6, 6), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{7, UPB_SIZE(48, 72), UPB_SIZE(7, 7), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{8, UPB_SIZE(56, 88), UPB_SIZE(8, 8), 0, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
{8, UPB_SIZE(56, 88), UPB_SIZE(8, 8), 2, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
{9, UPB_SIZE(16, 16), UPB_SIZE(9, 9), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{10, UPB_SIZE(60, 96), UPB_SIZE(10, 10), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{17, UPB_SIZE(20, 20), UPB_SIZE(11, 11), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
@ -249,14 +251,15 @@ const upb_MiniTable google_protobuf_MethodDescriptorProto_msginit = {
UPB_SIZE(32, 72), 6, kUpb_ExtMode_NonExtendable, 6, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_FileOptions_submsgs[1] = {
static const upb_MiniTable_Sub google_protobuf_FileOptions_submsgs[2] = {
{.subenum = &google_protobuf_FileOptions_OptimizeMode_enuminit},
{.submsg = &google_protobuf_UninterpretedOption_msginit},
};
static const upb_MiniTable_Field google_protobuf_FileOptions__fields[21] = {
{1, UPB_SIZE(20, 24), UPB_SIZE(1, 1), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{8, UPB_SIZE(28, 40), UPB_SIZE(2, 2), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{9, UPB_SIZE(4, 4), UPB_SIZE(3, 3), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{9, UPB_SIZE(4, 4), UPB_SIZE(3, 3), 0, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{10, UPB_SIZE(8, 8), UPB_SIZE(4, 4), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{11, UPB_SIZE(36, 56), UPB_SIZE(5, 5), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{16, UPB_SIZE(9, 9), UPB_SIZE(6, 6), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
@ -274,7 +277,7 @@ static const upb_MiniTable_Field google_protobuf_FileOptions__fields[21] = {
{42, UPB_SIZE(16, 16), UPB_SIZE(18, 18), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{44, UPB_SIZE(84, 152), UPB_SIZE(19, 19), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{45, UPB_SIZE(92, 168), UPB_SIZE(20, 20), kUpb_NoSub, 12, kUpb_FieldMode_Scalar | (kUpb_FieldRep_StringView << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(100, 184), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(100, 184), UPB_SIZE(0, 0), 1, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
};
const upb_MiniTable google_protobuf_FileOptions_msginit = {
@ -301,19 +304,21 @@ const upb_MiniTable google_protobuf_MessageOptions_msginit = {
UPB_SIZE(12, 24), 5, kUpb_ExtMode_Extendable, 3, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_FieldOptions_submsgs[1] = {
static const upb_MiniTable_Sub google_protobuf_FieldOptions_submsgs[3] = {
{.subenum = &google_protobuf_FieldOptions_CType_enuminit},
{.subenum = &google_protobuf_FieldOptions_JSType_enuminit},
{.submsg = &google_protobuf_UninterpretedOption_msginit},
};
static const upb_MiniTable_Field google_protobuf_FieldOptions__fields[8] = {
{1, UPB_SIZE(4, 4), UPB_SIZE(1, 1), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{1, UPB_SIZE(4, 4), UPB_SIZE(1, 1), 0, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{2, UPB_SIZE(8, 8), UPB_SIZE(2, 2), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{3, UPB_SIZE(9, 9), UPB_SIZE(3, 3), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{5, UPB_SIZE(10, 10), UPB_SIZE(4, 4), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{6, UPB_SIZE(12, 12), UPB_SIZE(5, 5), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{6, UPB_SIZE(12, 12), UPB_SIZE(5, 5), 1, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{10, UPB_SIZE(16, 16), UPB_SIZE(6, 6), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{15, UPB_SIZE(17, 17), UPB_SIZE(7, 7), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(20, 24), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(20, 24), UPB_SIZE(0, 0), 2, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
};
const upb_MiniTable google_protobuf_FieldOptions_msginit = {
@ -382,14 +387,15 @@ const upb_MiniTable google_protobuf_ServiceOptions_msginit = {
UPB_SIZE(8, 24), 2, kUpb_ExtMode_Extendable, 0, 255, 0,
};
static const upb_MiniTable_Sub google_protobuf_MethodOptions_submsgs[1] = {
static const upb_MiniTable_Sub google_protobuf_MethodOptions_submsgs[2] = {
{.subenum = &google_protobuf_MethodOptions_IdempotencyLevel_enuminit},
{.submsg = &google_protobuf_UninterpretedOption_msginit},
};
static const upb_MiniTable_Field google_protobuf_MethodOptions__fields[3] = {
{33, UPB_SIZE(1, 1), UPB_SIZE(1, 1), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{34, UPB_SIZE(4, 4), UPB_SIZE(2, 2), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(8, 8), UPB_SIZE(0, 0), 0, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
{34, UPB_SIZE(4, 4), UPB_SIZE(2, 2), 0, 14, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{999, UPB_SIZE(8, 8), UPB_SIZE(0, 0), 1, 11, kUpb_FieldMode_Array | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
};
const upb_MiniTable google_protobuf_MethodOptions_msginit = {

@ -61,7 +61,7 @@ typedef enum {
typedef enum {
kUpb_EncodedFieldModifier_FlipPacked = 1 << 0,
kUpb_EncodedFieldModifier_JspbString = 1 << 1,
kUpb_EncodedFieldModifier_IsClosedEnum = 1 << 1,
// upb only.
kUpb_EncodedFieldModifier_IsProto3Singular = 1 << 2,
kUpb_EncodedFieldModifier_IsRequired = 1 << 3,
@ -219,6 +219,11 @@ char* upb_MtDataEncoder_PutField(upb_MtDataEncoder* e, char* ptr,
uint32_t encoded_modifiers = 0;
// Put field type.
if (type == kUpb_FieldType_Enum &&
!(field_mod & kUpb_FieldModifier_IsClosedEnum)) {
type = kUpb_FieldType_Int32;
}
int encoded_type = kUpb_TypeToEncoded[type];
if (field_mod & kUpb_FieldModifier_IsRepeated) {
// Repeated fields shift the type number up (unlike other modifiers which
@ -374,12 +379,7 @@ static bool upb_MiniTable_HasSub(upb_MiniTable_Field* field,
field->descriptortype == kUpb_FieldType_Group) {
return true;
} else if (field->descriptortype == kUpb_FieldType_Enum) {
if (false) { // XXX (msg_modifiers & kUpb_MessageModifier_HasClosedEnums) {
return true;
} else {
field->descriptortype = kUpb_FieldType_Int32;
return false;
}
return true;
} else if (field->descriptortype == kUpb_FieldType_String) {
if (!(msg_modifiers & kUpb_MessageModifier_ValidateUtf8)) {
field->descriptortype = kUpb_FieldType_Bytes;
@ -921,6 +921,7 @@ upb_MiniTable* upb_MiniTable_BuildMessageSet(upb_MiniTablePlatform platform,
upb_MiniTable* upb_MiniTable_BuildMapEntry(upb_FieldType key_type,
upb_FieldType value_type,
bool value_is_proto3_enum,
upb_MiniTablePlatform platform,
upb_Arena* arena) {
upb_MiniTable* ret = upb_Arena_Malloc(arena, sizeof(*ret));
@ -928,8 +929,10 @@ upb_MiniTable* upb_MiniTable_BuildMapEntry(upb_FieldType key_type,
if (!ret || !fields) return NULL;
upb_MiniTable_Sub* subs = NULL;
if (value_is_proto3_enum) value_type = kUpb_FieldType_Int32;
if (value_type == kUpb_FieldType_Message ||
value_type == kUpb_FieldType_Group) {
value_type == kUpb_FieldType_Group ||
value_type == kUpb_FieldType_Enum) {
subs = upb_Arena_Malloc(arena, sizeof(*subs));
if (!subs) return NULL;
}
@ -960,6 +963,53 @@ upb_MiniTable* upb_MiniTable_BuildMapEntry(upb_FieldType key_type,
return ret;
}
upb_MiniTable_Enum* upb_MiniTable_BuildEnum(const char* data, size_t len,
upb_Arena* arena,
upb_Status* status) {
upb_MtDecoder decoder = {
.status = status,
};
if (UPB_SETJMP(decoder.err)) {
return NULL;
}
upb_MiniTable_Enum* table = upb_Arena_Malloc(arena, sizeof(*table));
upb_MtDecoder_CheckOutOfMemory(&decoder, table);
table->mask = 0;
table->value_count = 0;
table->values = NULL;
const char* ptr = data;
const char* end = UPB_PTRADD(data, len);
// Currently we do minimal validation of invariants (eg. that values are in
// order). We may want to add these, but more likely, we will want the format
// to be a more compact variation where these errors are not possible.
while (end - ptr >= 4) {
uint32_t val;
memcpy(&val, ptr, 4);
if (val >= 64) break;
table->mask |= 1ULL << val;
ptr += 4;
}
if (ptr != end) {
size_t bytes = end - ptr;
if (bytes / 4 * 4 != bytes) {
upb_MtDecoder_ErrorFormat(&decoder, "Bytes should be a multiple of 4");
UPB_UNREACHABLE();
}
table->values = upb_Arena_Malloc(arena, end - ptr);
upb_MtDecoder_CheckOutOfMemory(&decoder, table);
memcpy((void*)table->values, ptr, end - ptr);
table->value_count = bytes / 4;
}
return table;
}
bool upb_MiniTable_BuildExtension(const char* data, size_t len,
upb_MiniTable_Extension* ext,
upb_MiniTable_Sub sub, upb_Status* status) {

@ -41,18 +41,17 @@ const upb_MiniTable_Field* upb_MiniTable_FindFieldByNumber(
const upb_MiniTable* table, uint32_t number);
typedef enum {
kUpb_MessageModifier_ValidateUtf8 = 1,
kUpb_MessageModifier_DefaultIsPacked = 2,
kUpb_MessageModifier_HasClosedEnums = 4,
kUpb_MessageModifier_IsExtendable = 8,
kUpb_MessageModifier_IsMapEntry = 16,
kUpb_MessageModifier_ValidateUtf8 = 1 << 0,
kUpb_MessageModifier_DefaultIsPacked = 1 << 1,
kUpb_MessageModifier_IsExtendable = 1 << 2,
} kUpb_MessageModifier;
typedef enum {
kUpb_FieldModifier_IsRepeated = 1,
kUpb_FieldModifier_IsPacked = 2,
kUpb_FieldModifier_IsProto3Singular = 4,
kUpb_FieldModifier_IsRequired = 8,
kUpb_FieldModifier_IsRepeated = 1 << 0,
kUpb_FieldModifier_IsPacked = 1 << 1,
kUpb_FieldModifier_IsClosedEnum = 1 << 2,
kUpb_FieldModifier_IsProto3Singular = 1 << 3,
kUpb_FieldModifier_IsRequired = 1 << 4,
} kUpb_FieldModifier;
/** upb_MtDataEncoder *********************************************************/
@ -102,6 +101,13 @@ char* upb_MtDataEncoder_StartOneof(upb_MtDataEncoder* e, char* ptr);
char* upb_MtDataEncoder_PutOneofField(upb_MtDataEncoder* e, char* ptr,
uint32_t field_num);
// Encodes the set of values for a given enum. The values must be given in
// order (after casting to uint32_t), and repeats are not allowed.
char* upb_MtDataEncoder_StartEnum(upb_MtDataEncoder* e, char* ptr);
char* upb_MtDataEncoder_PutEnumValue(upb_MtDataEncoder* e, char* ptr,
uint32_t val);
char* upb_MtDataEncoder_FinishEnum(upb_MtDataEncoder* e, char* ptr);
/** upb_MiniTable *************************************************************/
typedef enum {
@ -133,9 +139,14 @@ upb_MiniTable* upb_MiniTable_BuildMessageSet(upb_MiniTablePlatform platform,
upb_Arena* arena);
upb_MiniTable* upb_MiniTable_BuildMapEntry(upb_FieldType key_type,
upb_FieldType value_type,
bool value_is_proto3_enum,
upb_MiniTablePlatform platform,
upb_Arena* arena);
upb_MiniTable_Enum* upb_MiniTable_BuildEnum(const char* data, size_t len,
upb_Arena* arena,
upb_Status* status);
// Like upb_MiniTable_Build(), but the user provides a buffer of layout data so
// it can be reused from call to call, avoiding repeated realloc()/free().
//

@ -196,15 +196,10 @@ UPB_INLINE size_t _upb_ArenaHas(upb_Arena* a) {
return (size_t)(h->end - h->ptr);
}
#include <stdio.h>
UPB_INLINE void* _upb_Arena_FastMalloc(upb_Arena* a, size_t size) {
_upb_ArenaHead* h = (_upb_ArenaHead*)a;
void* ret = h->ptr;
UPB_ASSERT(UPB_ALIGN_MALLOC((uintptr_t)ret) == (uintptr_t)ret);
if (UPB_ALIGN_MALLOC(size) != size) {
fprintf(stderr, "YO: %d vs %d\n", (int)UPB_ALIGN_MALLOC(size), (int)size);
}
UPB_ASSERT(UPB_ALIGN_MALLOC(size) == size);
UPB_UNPOISON_MEMORY_REGION(ret, size);

@ -38,6 +38,9 @@
#include "upb/upb.hpp"
#include "upbc/common.h"
// Must be last.
#include "upb/port_def.inc"
namespace upbc {
namespace {
@ -472,8 +475,11 @@ class FilePlatformLayout {
} else if (m->options().map_entry()) {
return upb_MiniTable_BuildMapEntry(
static_cast<upb_FieldType>(m->map_key()->type()),
static_cast<upb_FieldType>(m->map_value()->type()), platform_,
arena_.ptr());
static_cast<upb_FieldType>(m->map_value()->type()),
m->map_value()->enum_type() &&
m->map_value()->enum_type()->file()->syntax() ==
protobuf::FileDescriptor::SYNTAX_PROTO3,
platform_, arena_.ptr());
} else {
return MakeRegularMiniTable(m);
}
@ -508,9 +514,7 @@ class FilePlatformLayout {
uint64_t GetMessageModifiers(const protobuf::Descriptor* m) {
uint64_t ret = 0;
if (m->file()->syntax() == protobuf::FileDescriptor::SYNTAX_PROTO2) {
ret |= kUpb_MessageModifier_HasClosedEnums;
} else {
if (m->file()->syntax() == protobuf::FileDescriptor::SYNTAX_PROTO3) {
ret |= kUpb_MessageModifier_ValidateUtf8;
ret |= kUpb_MessageModifier_DefaultIsPacked;
}
@ -529,6 +533,10 @@ class FilePlatformLayout {
if (f->is_repeated()) ret |= kUpb_FieldModifier_IsRepeated;
if (f->is_required()) ret |= kUpb_FieldModifier_IsRequired;
if (f->is_packed()) ret |= kUpb_FieldModifier_IsPacked;
if (f->enum_type() && f->enum_type()->file()->syntax() ==
protobuf::FileDescriptor::SYNTAX_PROTO2) {
ret |= kUpb_FieldModifier_IsClosedEnum;
}
if (f->is_optional() && !f->has_presence()) {
ret |= kUpb_FieldModifier_IsProto3Singular;
}
@ -1245,7 +1253,6 @@ int GetTableSlot(const protobuf::FieldDescriptor* field) {
return (tag & 0xf8) >> 3;
}
#include "upb/port_def.inc"
bool TryFillTableEntry(const FileLayout& layout,
const protobuf::FieldDescriptor* field,
TableEntry& ent) {

Loading…
Cancel
Save