diff --git a/BUILD b/BUILD index 633825cc21..5bed64617f 100644 --- a/BUILD +++ b/BUILD @@ -109,6 +109,7 @@ cc_library( cc_library( name = "fastdecode", srcs = [ + "upb/decode.h", "upb/decode_internal.h", "upb/decode_fast.c", "upb/decode_fast.h", diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index c627271437..82d518cdbc 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -82,6 +82,7 @@ target_link_libraries(upb port /third_party/utf8_range) add_library(fastdecode + ../upb/decode.h ../upb/decode_internal.h ../upb/decode_fast.c ../upb/decode_fast.h diff --git a/cmake/google/protobuf/descriptor.upb.c b/cmake/google/protobuf/descriptor.upb.c index 588e431977..007d65199b 100644 --- a/cmake/google/protobuf/descriptor.upb.c +++ b/cmake/google/protobuf/descriptor.upb.c @@ -23,7 +23,7 @@ static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] = const upb_msglayout google_protobuf_FileDescriptorSet_msginit = { &google_protobuf_FileDescriptorSet_submsgs[0], &google_protobuf_FileDescriptorSet__fields[0], - UPB_SIZE(8, 8), 1, _UPB_MSGEXT_NONE, 1, 255, + 0, UPB_SIZE(8, 8), 1, _UPB_MSGEXT_NONE, 1, 255, }; static const upb_msglayout_sub google_protobuf_FileDescriptorProto_submsgs[6] = { @@ -53,7 +53,7 @@ static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12] const upb_msglayout google_protobuf_FileDescriptorProto_msginit = { &google_protobuf_FileDescriptorProto_submsgs[0], &google_protobuf_FileDescriptorProto__fields[0], - UPB_SIZE(64, 128), 12, _UPB_MSGEXT_NONE, 12, 255, + 0, UPB_SIZE(64, 128), 12, _UPB_MSGEXT_NONE, 12, 255, }; static const upb_msglayout_sub google_protobuf_DescriptorProto_submsgs[7] = { @@ -82,7 +82,7 @@ static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = { const upb_msglayout google_protobuf_DescriptorProto_msginit = { &google_protobuf_DescriptorProto_submsgs[0], &google_protobuf_DescriptorProto__fields[0], - UPB_SIZE(48, 96), 10, _UPB_MSGEXT_NONE, 10, 255, + 0, UPB_SIZE(48, 96), 10, _UPB_MSGEXT_NONE, 10, 255, }; static const upb_msglayout_sub google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = { @@ -98,7 +98,7 @@ static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange_ const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = { &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0], &google_protobuf_DescriptorProto_ExtensionRange__fields[0], - UPB_SIZE(16, 24), 3, _UPB_MSGEXT_NONE, 3, 255, + 0, UPB_SIZE(16, 24), 3, _UPB_MSGEXT_NONE, 3, 255, }; static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2] = { @@ -109,7 +109,7 @@ static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__ const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = { NULL, &google_protobuf_DescriptorProto_ReservedRange__fields[0], - UPB_SIZE(16, 16), 2, _UPB_MSGEXT_NONE, 2, 255, + 0, UPB_SIZE(16, 16), 2, _UPB_MSGEXT_NONE, 2, 255, }; static const upb_msglayout_sub google_protobuf_ExtensionRangeOptions_submsgs[1] = { @@ -123,7 +123,7 @@ static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1 const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = { &google_protobuf_ExtensionRangeOptions_submsgs[0], &google_protobuf_ExtensionRangeOptions__fields[0], - UPB_SIZE(8, 8), 1, _UPB_MSGEXT_EXTENDABLE, 0, 255, + 0, UPB_SIZE(8, 8), 1, _UPB_MSGEXT_EXTENDABLE, 0, 255, }; static const upb_msglayout_sub google_protobuf_FieldDescriptorProto_submsgs[3] = { @@ -149,7 +149,7 @@ static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11 const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = { &google_protobuf_FieldDescriptorProto_submsgs[0], &google_protobuf_FieldDescriptorProto__fields[0], - UPB_SIZE(72, 112), 11, _UPB_MSGEXT_NONE, 10, 255, + 0, UPB_SIZE(72, 112), 11, _UPB_MSGEXT_NONE, 10, 255, }; static const upb_msglayout_sub google_protobuf_OneofDescriptorProto_submsgs[1] = { @@ -164,7 +164,7 @@ static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2] const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = { &google_protobuf_OneofDescriptorProto_submsgs[0], &google_protobuf_OneofDescriptorProto__fields[0], - UPB_SIZE(16, 32), 2, _UPB_MSGEXT_NONE, 2, 255, + 0, UPB_SIZE(16, 32), 2, _UPB_MSGEXT_NONE, 2, 255, }; static const upb_msglayout_sub google_protobuf_EnumDescriptorProto_submsgs[3] = { @@ -184,7 +184,7 @@ static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5] const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = { &google_protobuf_EnumDescriptorProto_submsgs[0], &google_protobuf_EnumDescriptorProto__fields[0], - UPB_SIZE(32, 64), 5, _UPB_MSGEXT_NONE, 5, 255, + 0, UPB_SIZE(32, 64), 5, _UPB_MSGEXT_NONE, 5, 255, }; static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = { @@ -195,7 +195,7 @@ static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReserve const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = { NULL, &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0], - UPB_SIZE(16, 16), 2, _UPB_MSGEXT_NONE, 2, 255, + 0, UPB_SIZE(16, 16), 2, _UPB_MSGEXT_NONE, 2, 255, }; static const upb_msglayout_sub google_protobuf_EnumValueDescriptorProto_submsgs[1] = { @@ -211,7 +211,7 @@ static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__field const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = { &google_protobuf_EnumValueDescriptorProto_submsgs[0], &google_protobuf_EnumValueDescriptorProto__fields[0], - UPB_SIZE(24, 32), 3, _UPB_MSGEXT_NONE, 3, 255, + 0, UPB_SIZE(24, 32), 3, _UPB_MSGEXT_NONE, 3, 255, }; static const upb_msglayout_sub google_protobuf_ServiceDescriptorProto_submsgs[2] = { @@ -228,7 +228,7 @@ static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[ const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = { &google_protobuf_ServiceDescriptorProto_submsgs[0], &google_protobuf_ServiceDescriptorProto__fields[0], - UPB_SIZE(24, 48), 3, _UPB_MSGEXT_NONE, 3, 255, + 0, UPB_SIZE(24, 48), 3, _UPB_MSGEXT_NONE, 3, 255, }; static const upb_msglayout_sub google_protobuf_MethodDescriptorProto_submsgs[1] = { @@ -247,7 +247,7 @@ static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6 const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = { &google_protobuf_MethodDescriptorProto_submsgs[0], &google_protobuf_MethodDescriptorProto__fields[0], - UPB_SIZE(32, 64), 6, _UPB_MSGEXT_NONE, 6, 255, + 0, UPB_SIZE(32, 64), 6, _UPB_MSGEXT_NONE, 6, 255, }; static const upb_msglayout_sub google_protobuf_FileOptions_submsgs[2] = { @@ -282,7 +282,7 @@ static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = { const upb_msglayout google_protobuf_FileOptions_msginit = { &google_protobuf_FileOptions_submsgs[0], &google_protobuf_FileOptions__fields[0], - UPB_SIZE(104, 192), 21, _UPB_MSGEXT_EXTENDABLE, 1, 255, + 0, UPB_SIZE(104, 192), 21, _UPB_MSGEXT_EXTENDABLE, 1, 255, }; static const upb_msglayout_sub google_protobuf_MessageOptions_submsgs[1] = { @@ -300,7 +300,7 @@ static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = { const upb_msglayout google_protobuf_MessageOptions_msginit = { &google_protobuf_MessageOptions_submsgs[0], &google_protobuf_MessageOptions__fields[0], - UPB_SIZE(16, 16), 5, _UPB_MSGEXT_EXTENDABLE, 3, 255, + 0, UPB_SIZE(16, 16), 5, _UPB_MSGEXT_EXTENDABLE, 3, 255, }; static const upb_msglayout_sub google_protobuf_FieldOptions_submsgs[3] = { @@ -322,7 +322,7 @@ static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = { const upb_msglayout google_protobuf_FieldOptions_msginit = { &google_protobuf_FieldOptions_submsgs[0], &google_protobuf_FieldOptions__fields[0], - UPB_SIZE(24, 24), 7, _UPB_MSGEXT_EXTENDABLE, 3, 255, + 0, UPB_SIZE(24, 24), 7, _UPB_MSGEXT_EXTENDABLE, 3, 255, }; static const upb_msglayout_sub google_protobuf_OneofOptions_submsgs[1] = { @@ -336,7 +336,7 @@ static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = { const upb_msglayout google_protobuf_OneofOptions_msginit = { &google_protobuf_OneofOptions_submsgs[0], &google_protobuf_OneofOptions__fields[0], - UPB_SIZE(8, 8), 1, _UPB_MSGEXT_EXTENDABLE, 0, 255, + 0, UPB_SIZE(8, 8), 1, _UPB_MSGEXT_EXTENDABLE, 0, 255, }; static const upb_msglayout_sub google_protobuf_EnumOptions_submsgs[1] = { @@ -352,7 +352,7 @@ static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = { const upb_msglayout google_protobuf_EnumOptions_msginit = { &google_protobuf_EnumOptions_submsgs[0], &google_protobuf_EnumOptions__fields[0], - UPB_SIZE(8, 16), 3, _UPB_MSGEXT_EXTENDABLE, 0, 255, + 0, UPB_SIZE(8, 16), 3, _UPB_MSGEXT_EXTENDABLE, 0, 255, }; static const upb_msglayout_sub google_protobuf_EnumValueOptions_submsgs[1] = { @@ -367,7 +367,7 @@ static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = { const upb_msglayout google_protobuf_EnumValueOptions_msginit = { &google_protobuf_EnumValueOptions_submsgs[0], &google_protobuf_EnumValueOptions__fields[0], - UPB_SIZE(8, 16), 2, _UPB_MSGEXT_EXTENDABLE, 1, 255, + 0, UPB_SIZE(8, 16), 2, _UPB_MSGEXT_EXTENDABLE, 1, 255, }; static const upb_msglayout_sub google_protobuf_ServiceOptions_submsgs[1] = { @@ -382,7 +382,7 @@ static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = { const upb_msglayout google_protobuf_ServiceOptions_msginit = { &google_protobuf_ServiceOptions_submsgs[0], &google_protobuf_ServiceOptions__fields[0], - UPB_SIZE(8, 16), 2, _UPB_MSGEXT_EXTENDABLE, 0, 255, + 0, UPB_SIZE(8, 16), 2, _UPB_MSGEXT_EXTENDABLE, 0, 255, }; static const upb_msglayout_sub google_protobuf_MethodOptions_submsgs[2] = { @@ -399,7 +399,7 @@ static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = { const upb_msglayout google_protobuf_MethodOptions_msginit = { &google_protobuf_MethodOptions_submsgs[0], &google_protobuf_MethodOptions__fields[0], - UPB_SIZE(16, 24), 3, _UPB_MSGEXT_EXTENDABLE, 0, 255, + 0, UPB_SIZE(16, 24), 3, _UPB_MSGEXT_EXTENDABLE, 0, 255, }; static const upb_msglayout_sub google_protobuf_UninterpretedOption_submsgs[1] = { @@ -419,7 +419,7 @@ static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] const upb_msglayout google_protobuf_UninterpretedOption_msginit = { &google_protobuf_UninterpretedOption_submsgs[0], &google_protobuf_UninterpretedOption__fields[0], - UPB_SIZE(64, 96), 7, _UPB_MSGEXT_NONE, 0, 255, + 0, UPB_SIZE(64, 96), 7, _UPB_MSGEXT_NONE, 0, 255, }; static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = { @@ -430,7 +430,7 @@ static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__f const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = { NULL, &google_protobuf_UninterpretedOption_NamePart__fields[0], - UPB_SIZE(16, 32), 2, _UPB_MSGEXT_NONE, 2, 255, + 6, UPB_SIZE(16, 32), 2, _UPB_MSGEXT_NONE, 2, 255, }; static const upb_msglayout_sub google_protobuf_SourceCodeInfo_submsgs[1] = { @@ -444,7 +444,7 @@ static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = { const upb_msglayout google_protobuf_SourceCodeInfo_msginit = { &google_protobuf_SourceCodeInfo_submsgs[0], &google_protobuf_SourceCodeInfo__fields[0], - UPB_SIZE(8, 8), 1, _UPB_MSGEXT_NONE, 1, 255, + 0, UPB_SIZE(8, 8), 1, _UPB_MSGEXT_NONE, 1, 255, }; static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = { @@ -458,7 +458,7 @@ static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = { NULL, &google_protobuf_SourceCodeInfo_Location__fields[0], - UPB_SIZE(32, 64), 5, _UPB_MSGEXT_NONE, 4, 255, + 0, UPB_SIZE(32, 64), 5, _UPB_MSGEXT_NONE, 4, 255, }; static const upb_msglayout_sub google_protobuf_GeneratedCodeInfo_submsgs[1] = { @@ -472,7 +472,7 @@ static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] = const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = { &google_protobuf_GeneratedCodeInfo_submsgs[0], &google_protobuf_GeneratedCodeInfo__fields[0], - UPB_SIZE(8, 8), 1, _UPB_MSGEXT_NONE, 1, 255, + 0, UPB_SIZE(8, 8), 1, _UPB_MSGEXT_NONE, 1, 255, }; static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = { @@ -485,7 +485,7 @@ static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__f const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = { NULL, &google_protobuf_GeneratedCodeInfo_Annotation__fields[0], - UPB_SIZE(24, 48), 4, _UPB_MSGEXT_NONE, 4, 255, + 0, UPB_SIZE(24, 48), 4, _UPB_MSGEXT_NONE, 4, 255, }; static const upb_msglayout *messages_layout[27] = { @@ -518,15 +518,21 @@ static const upb_msglayout *messages_layout[27] = { &google_protobuf_GeneratedCodeInfo_Annotation_msginit, }; +const upb_enumlayout google_protobuf_FieldDescriptorProto_Type_enuminit = { + NULL, + 0x7fffeULL, + 0, +}; + const upb_enumlayout google_protobuf_FieldDescriptorProto_Label_enuminit = { NULL, 0xeULL, 0, }; -const upb_enumlayout google_protobuf_FieldDescriptorProto_Type_enuminit = { +const upb_enumlayout google_protobuf_FileOptions_OptimizeMode_enuminit = { NULL, - 0x7fffeULL, + 0xeULL, 0, }; @@ -542,12 +548,6 @@ const upb_enumlayout google_protobuf_FieldOptions_JSType_enuminit = { 0, }; -const upb_enumlayout google_protobuf_FileOptions_OptimizeMode_enuminit = { - NULL, - 0xeULL, - 0, -}; - const upb_enumlayout google_protobuf_MethodOptions_IdempotencyLevel_enuminit = { NULL, 0x7ULL, @@ -555,11 +555,11 @@ const upb_enumlayout google_protobuf_MethodOptions_IdempotencyLevel_enuminit = { }; static const upb_enumlayout *enums_layout[6] = { - &google_protobuf_FieldDescriptorProto_Label_enuminit, &google_protobuf_FieldDescriptorProto_Type_enuminit, + &google_protobuf_FieldDescriptorProto_Label_enuminit, + &google_protobuf_FileOptions_OptimizeMode_enuminit, &google_protobuf_FieldOptions_CType_enuminit, &google_protobuf_FieldOptions_JSType_enuminit, - &google_protobuf_FileOptions_OptimizeMode_enuminit, &google_protobuf_MethodOptions_IdempotencyLevel_enuminit, }; diff --git a/cmake/google/protobuf/descriptor.upb.h b/cmake/google/protobuf/descriptor.upb.h index ad6fb7eac0..f3d7963fc9 100644 --- a/cmake/google/protobuf/descriptor.upb.h +++ b/cmake/google/protobuf/descriptor.upb.h @@ -102,12 +102,6 @@ extern const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit; extern const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit; extern const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit; -typedef enum { - google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1, - google_protobuf_FieldDescriptorProto_LABEL_REQUIRED = 2, - google_protobuf_FieldDescriptorProto_LABEL_REPEATED = 3 -} google_protobuf_FieldDescriptorProto_Label; - typedef enum { google_protobuf_FieldDescriptorProto_TYPE_DOUBLE = 1, google_protobuf_FieldDescriptorProto_TYPE_FLOAT = 2, @@ -129,6 +123,18 @@ typedef enum { google_protobuf_FieldDescriptorProto_TYPE_SINT64 = 18 } google_protobuf_FieldDescriptorProto_Type; +typedef enum { + google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1, + google_protobuf_FieldDescriptorProto_LABEL_REQUIRED = 2, + google_protobuf_FieldDescriptorProto_LABEL_REPEATED = 3 +} google_protobuf_FieldDescriptorProto_Label; + +typedef enum { + google_protobuf_FileOptions_SPEED = 1, + google_protobuf_FileOptions_CODE_SIZE = 2, + google_protobuf_FileOptions_LITE_RUNTIME = 3 +} google_protobuf_FileOptions_OptimizeMode; + typedef enum { google_protobuf_FieldOptions_STRING = 0, google_protobuf_FieldOptions_CORD = 1, @@ -141,12 +147,6 @@ typedef enum { google_protobuf_FieldOptions_JS_NUMBER = 2 } google_protobuf_FieldOptions_JSType; -typedef enum { - google_protobuf_FileOptions_SPEED = 1, - google_protobuf_FileOptions_CODE_SIZE = 2, - google_protobuf_FileOptions_LITE_RUNTIME = 3 -} google_protobuf_FileOptions_OptimizeMode; - typedef enum { google_protobuf_MethodOptions_IDEMPOTENCY_UNKNOWN = 0, google_protobuf_MethodOptions_NO_SIDE_EFFECTS = 1, @@ -154,11 +154,11 @@ typedef enum { } google_protobuf_MethodOptions_IdempotencyLevel; -extern const upb_enumlayout google_protobuf_FieldDescriptorProto_Label_enuminit; extern const upb_enumlayout google_protobuf_FieldDescriptorProto_Type_enuminit; +extern const upb_enumlayout google_protobuf_FieldDescriptorProto_Label_enuminit; +extern const upb_enumlayout google_protobuf_FileOptions_OptimizeMode_enuminit; extern const upb_enumlayout google_protobuf_FieldOptions_CType_enuminit; extern const upb_enumlayout google_protobuf_FieldOptions_JSType_enuminit; -extern const upb_enumlayout google_protobuf_FileOptions_OptimizeMode_enuminit; extern const upb_enumlayout google_protobuf_MethodOptions_IdempotencyLevel_enuminit; /* google.protobuf.FileDescriptorSet */ @@ -170,7 +170,7 @@ UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_ upb_arena *arena) { google_protobuf_FileDescriptorSet *ret = google_protobuf_FileDescriptorSet_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_parse_ex(const char *buf, size_t size, @@ -178,7 +178,7 @@ UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_ upb_arena *arena) { google_protobuf_FileDescriptorSet *ret = google_protobuf_FileDescriptorSet_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -213,7 +213,7 @@ UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorPr upb_arena *arena) { google_protobuf_FileDescriptorProto *ret = google_protobuf_FileDescriptorProto_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_parse_ex(const char *buf, size_t size, @@ -221,7 +221,7 @@ UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorPr upb_arena *arena) { google_protobuf_FileDescriptorProto *ret = google_protobuf_FileDescriptorProto_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -382,7 +382,7 @@ UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_pars upb_arena *arena) { google_protobuf_DescriptorProto *ret = google_protobuf_DescriptorProto_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_parse_ex(const char *buf, size_t size, @@ -390,7 +390,7 @@ UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_pars upb_arena *arena) { google_protobuf_DescriptorProto *ret = google_protobuf_DescriptorProto_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -547,7 +547,7 @@ UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_Descr upb_arena *arena) { google_protobuf_DescriptorProto_ExtensionRange *ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_parse_ex(const char *buf, size_t size, @@ -555,7 +555,7 @@ UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_Descr upb_arena *arena) { google_protobuf_DescriptorProto_ExtensionRange *ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -602,7 +602,7 @@ UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_Descri upb_arena *arena) { google_protobuf_DescriptorProto_ReservedRange *ret = google_protobuf_DescriptorProto_ReservedRange_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_parse_ex(const char *buf, size_t size, @@ -610,7 +610,7 @@ UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_Descri upb_arena *arena) { google_protobuf_DescriptorProto_ReservedRange *ret = google_protobuf_DescriptorProto_ReservedRange_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -642,7 +642,7 @@ UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRange upb_arena *arena) { google_protobuf_ExtensionRangeOptions *ret = google_protobuf_ExtensionRangeOptions_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_parse_ex(const char *buf, size_t size, @@ -650,7 +650,7 @@ UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRange upb_arena *arena) { google_protobuf_ExtensionRangeOptions *ret = google_protobuf_ExtensionRangeOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -685,7 +685,7 @@ UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptor upb_arena *arena) { google_protobuf_FieldDescriptorProto *ret = google_protobuf_FieldDescriptorProto_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_parse_ex(const char *buf, size_t size, @@ -693,7 +693,7 @@ UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptor upb_arena *arena) { google_protobuf_FieldDescriptorProto *ret = google_protobuf_FieldDescriptorProto_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -709,9 +709,9 @@ UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const googl UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 3); } UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 12), int32_t); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 4); } -UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return google_protobuf_FieldDescriptorProto_has_label(msg) ? *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) : 1; } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 5); } -UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t); } +UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return google_protobuf_FieldDescriptorProto_has_type(msg) ? *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) : 1; } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 6); } UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(40, 56), upb_strview); } UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_hasbit(msg, 7); } @@ -788,7 +788,7 @@ UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptor upb_arena *arena) { google_protobuf_OneofDescriptorProto *ret = google_protobuf_OneofDescriptorProto_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_parse_ex(const char *buf, size_t size, @@ -796,7 +796,7 @@ UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptor upb_arena *arena) { google_protobuf_OneofDescriptorProto *ret = google_protobuf_OneofDescriptorProto_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -837,7 +837,7 @@ UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorPr upb_arena *arena) { google_protobuf_EnumDescriptorProto *ret = google_protobuf_EnumDescriptorProto_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_parse_ex(const char *buf, size_t size, @@ -845,7 +845,7 @@ UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorPr upb_arena *arena) { google_protobuf_EnumDescriptorProto *ret = google_protobuf_EnumDescriptorProto_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -927,7 +927,7 @@ UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobu upb_arena *arena) { google_protobuf_EnumDescriptorProto_EnumReservedRange *ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_parse_ex(const char *buf, size_t size, @@ -935,7 +935,7 @@ UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobu upb_arena *arena) { google_protobuf_EnumDescriptorProto_EnumReservedRange *ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -967,7 +967,7 @@ UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDe upb_arena *arena) { google_protobuf_EnumValueDescriptorProto *ret = google_protobuf_EnumValueDescriptorProto_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_parse_ex(const char *buf, size_t size, @@ -975,7 +975,7 @@ UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDe upb_arena *arena) { google_protobuf_EnumValueDescriptorProto *ret = google_protobuf_EnumValueDescriptorProto_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -1022,7 +1022,7 @@ UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescri upb_arena *arena) { google_protobuf_ServiceDescriptorProto *ret = google_protobuf_ServiceDescriptorProto_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_parse_ex(const char *buf, size_t size, @@ -1030,7 +1030,7 @@ UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescri upb_arena *arena) { google_protobuf_ServiceDescriptorProto *ret = google_protobuf_ServiceDescriptorProto_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -1086,7 +1086,7 @@ UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescript upb_arena *arena) { google_protobuf_MethodDescriptorProto *ret = google_protobuf_MethodDescriptorProto_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_parse_ex(const char *buf, size_t size, @@ -1094,7 +1094,7 @@ UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescript upb_arena *arena) { google_protobuf_MethodDescriptorProto *ret = google_protobuf_MethodDescriptorProto_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -1159,7 +1159,7 @@ UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parse(const upb_arena *arena) { google_protobuf_FileOptions *ret = google_protobuf_FileOptions_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parse_ex(const char *buf, size_t size, @@ -1167,7 +1167,7 @@ UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parse_ex(con upb_arena *arena) { google_protobuf_FileOptions *ret = google_protobuf_FileOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -1181,7 +1181,7 @@ UPB_INLINE upb_strview google_protobuf_FileOptions_java_package(const google_pro UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 2); } UPB_INLINE upb_strview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(28, 40), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 3); } -UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t); } +UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return google_protobuf_FileOptions_has_optimize_for(msg) ? *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) : 1; } UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 4); } UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool); } UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 5); } @@ -1199,7 +1199,7 @@ UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_Fil UPB_INLINE bool google_protobuf_FileOptions_has_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 11); } UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(14, 14), bool); } UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 12); } -UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool); } +UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return google_protobuf_FileOptions_has_cc_enable_arenas(msg) ? *UPB_PTR_AT(msg, UPB_SIZE(15, 15), bool) : true; } UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 13); } UPB_INLINE upb_strview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(44, 72), upb_strview); } UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions *msg) { return _upb_hasbit(msg, 14); } @@ -1322,7 +1322,7 @@ UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parse( upb_arena *arena) { google_protobuf_MessageOptions *ret = google_protobuf_MessageOptions_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parse_ex(const char *buf, size_t size, @@ -1330,7 +1330,7 @@ UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parse_ upb_arena *arena) { google_protobuf_MessageOptions *ret = google_protobuf_MessageOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -1389,7 +1389,7 @@ UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parse(cons upb_arena *arena) { google_protobuf_FieldOptions *ret = google_protobuf_FieldOptions_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parse_ex(const char *buf, size_t size, @@ -1397,7 +1397,7 @@ UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parse_ex(c upb_arena *arena) { google_protobuf_FieldOptions *ret = google_protobuf_FieldOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -1468,7 +1468,7 @@ UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parse(cons upb_arena *arena) { google_protobuf_OneofOptions *ret = google_protobuf_OneofOptions_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parse_ex(const char *buf, size_t size, @@ -1476,7 +1476,7 @@ UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parse_ex(c upb_arena *arena) { google_protobuf_OneofOptions *ret = google_protobuf_OneofOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -1511,7 +1511,7 @@ UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parse(const upb_arena *arena) { google_protobuf_EnumOptions *ret = google_protobuf_EnumOptions_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parse_ex(const char *buf, size_t size, @@ -1519,7 +1519,7 @@ UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parse_ex(con upb_arena *arena) { google_protobuf_EnumOptions *ret = google_protobuf_EnumOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -1566,7 +1566,7 @@ UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_pa upb_arena *arena) { google_protobuf_EnumValueOptions *ret = google_protobuf_EnumValueOptions_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_parse_ex(const char *buf, size_t size, @@ -1574,7 +1574,7 @@ UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_pa upb_arena *arena) { google_protobuf_EnumValueOptions *ret = google_protobuf_EnumValueOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -1615,7 +1615,7 @@ UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parse( upb_arena *arena) { google_protobuf_ServiceOptions *ret = google_protobuf_ServiceOptions_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parse_ex(const char *buf, size_t size, @@ -1623,7 +1623,7 @@ UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parse_ upb_arena *arena) { google_protobuf_ServiceOptions *ret = google_protobuf_ServiceOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -1664,7 +1664,7 @@ UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parse(co upb_arena *arena) { google_protobuf_MethodOptions *ret = google_protobuf_MethodOptions_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parse_ex(const char *buf, size_t size, @@ -1672,7 +1672,7 @@ UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parse_ex upb_arena *arena) { google_protobuf_MethodOptions *ret = google_protobuf_MethodOptions_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -1719,7 +1719,7 @@ UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOpt upb_arena *arena) { google_protobuf_UninterpretedOption *ret = google_protobuf_UninterpretedOption_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_parse_ex(const char *buf, size_t size, @@ -1727,7 +1727,7 @@ UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOpt upb_arena *arena) { google_protobuf_UninterpretedOption *ret = google_protobuf_UninterpretedOption_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -1798,7 +1798,7 @@ UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_Uninter upb_arena *arena) { google_protobuf_UninterpretedOption_NamePart *ret = google_protobuf_UninterpretedOption_NamePart_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_parse_ex(const char *buf, size_t size, @@ -1806,7 +1806,7 @@ UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_Uninter upb_arena *arena) { google_protobuf_UninterpretedOption_NamePart *ret = google_protobuf_UninterpretedOption_NamePart_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -1838,7 +1838,7 @@ UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parse( upb_arena *arena) { google_protobuf_SourceCodeInfo *ret = google_protobuf_SourceCodeInfo_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parse_ex(const char *buf, size_t size, @@ -1846,7 +1846,7 @@ UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parse_ upb_arena *arena) { google_protobuf_SourceCodeInfo *ret = google_protobuf_SourceCodeInfo_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -1881,7 +1881,7 @@ UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeIn upb_arena *arena) { google_protobuf_SourceCodeInfo_Location *ret = google_protobuf_SourceCodeInfo_Location_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_parse_ex(const char *buf, size_t size, @@ -1889,7 +1889,7 @@ UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeIn upb_arena *arena) { google_protobuf_SourceCodeInfo_Location *ret = google_protobuf_SourceCodeInfo_Location_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -1954,7 +1954,7 @@ UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_ upb_arena *arena) { google_protobuf_GeneratedCodeInfo *ret = google_protobuf_GeneratedCodeInfo_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_parse_ex(const char *buf, size_t size, @@ -1962,7 +1962,7 @@ UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_ upb_arena *arena) { google_protobuf_GeneratedCodeInfo *ret = google_protobuf_GeneratedCodeInfo_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, extreg, options, arena)) { return NULL; } return ret; @@ -1997,7 +1997,7 @@ UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_Generat upb_arena *arena) { google_protobuf_GeneratedCodeInfo_Annotation *ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena); if (!ret) return NULL; - if (!upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena)) return NULL; + if (upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena)) return NULL; return ret; } UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_parse_ex(const char *buf, size_t size, @@ -2005,7 +2005,7 @@ UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_Generat upb_arena *arena) { google_protobuf_GeneratedCodeInfo_Annotation *ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena); if (!ret) return NULL; - if (!_upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, extreg, options, arena)) { + if (_upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, extreg, options, arena)) { return NULL; } return ret; diff --git a/tests/conformance_upb.c b/tests/conformance_upb.c index 12c7f1f469..6330433dd9 100644 --- a/tests/conformance_upb.c +++ b/tests/conformance_upb.c @@ -87,7 +87,8 @@ typedef struct { bool parse_proto(upb_msg *msg, const upb_msgdef *m, const ctx* c) { upb_strview proto = conformance_ConformanceRequest_protobuf_payload(c->request); - if (upb_decode(proto.data, proto.size, msg, upb_msgdef_layout(m), c->arena)) { + if (upb_decode(proto.data, proto.size, msg, upb_msgdef_layout(m), c->arena) == + UPB_DECODE_OK) { return true; } else { static const char msg[] = "Parse error"; diff --git a/tests/test_table.cc b/tests/test_table.cc index 84ede2be2d..1c44280b21 100644 --- a/tests/test_table.cc +++ b/tests/test_table.cc @@ -155,7 +155,7 @@ class StrTable { std::pair Remove(const std::string& key) { std::pair ret; ret.first = - upb_strtable_remove(&table_, key.c_str(), key.size(), &ret.second); + upb_strtable_remove2(&table_, key.c_str(), key.size(), &ret.second); return ret; } diff --git a/upb/bindings/lua/msg.c b/upb/bindings/lua/msg.c index 1b4d9ef0fd..530d9b3aad 100644 --- a/upb/bindings/lua/msg.c +++ b/upb/bindings/lua/msg.c @@ -961,7 +961,7 @@ static int lupb_decode(lua_State *L) { buf = upb_arena_malloc(arena, len); memcpy(buf, pb, len); - ok = _upb_decode(buf, len, msg, layout, NULL, UPB_DECODE_ALIAS, arena); + ok = _upb_decode(buf, len, msg, layout, NULL, UPB_DECODE_ALIAS, arena) == 0; if (!ok) { lua_pushstring(L, "Error decoding protobuf."); diff --git a/upb/decode.c b/upb/decode.c index 20a08fc29f..65e3934a8c 100644 --- a/upb/decode.c +++ b/upb/decode.c @@ -189,23 +189,22 @@ typedef union { static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, const upb_msglayout *layout); -UPB_NORETURN static const char *decode_err(upb_decstate *d) { - UPB_LONGJMP(d->err, 1); +UPB_NORETURN static void *decode_err(upb_decstate *d, upb_decodestatus status) { + UPB_LONGJMP(d->err, status); } -const char *fastdecode_err(upb_decstate *d) { - longjmp(d->err, 1); +const char *fastdecode_err(upb_decstate *d, int status) { + UPB_LONGJMP(d->err, status); return NULL; } - static void decode_verifyutf8(upb_decstate *d, const char *buf, int len) { - if (!decode_verifyutf8_inl(buf, len)) decode_err(d); + if (!decode_verifyutf8_inl(buf, len)) decode_err(d, UPB_DECODE_BAD_UTF8); } static bool decode_reserve(upb_decstate *d, upb_array *arr, size_t elem) { bool need_realloc = arr->size - arr->len < elem; if (need_realloc && !_upb_array_realloc(arr, arr->len + elem, &d->arena)) { - decode_err(d); + decode_err(d, UPB_DECODE_OOM); } return need_realloc; } @@ -241,15 +240,14 @@ static const char *decode_varint64(upb_decstate *d, const char *ptr, return ptr + 1; } else { decode_vret res = decode_longvarint64(ptr, byte); - if (!res.ptr) return decode_err(d); + if (!res.ptr) return decode_err(d, UPB_DECODE_MALFORMED); *val = res.val; return res.ptr; } } UPB_FORCEINLINE -static const char *decode_tag(upb_decstate *d, const char *ptr, - uint32_t *val) { +static const char *decode_tag(upb_decstate *d, const char *ptr, uint32_t *val) { uint64_t byte = (uint8_t)*ptr; if (UPB_LIKELY((byte & 0x80) == 0)) { *val = byte; @@ -259,7 +257,9 @@ static const char *decode_tag(upb_decstate *d, const char *ptr, decode_vret res = decode_longvarint64(ptr, byte); ptr = res.ptr; *val = res.val; - if (!ptr || *val > UINT32_MAX || ptr - start > 5) return decode_err(d); + if (!ptr || *val > UINT32_MAX || ptr - start > 5) { + return decode_err(d, UPB_DECODE_MALFORMED); + } return ptr; } } @@ -298,20 +298,21 @@ static upb_msg *decode_newsubmsg(upb_decstate *d, const upb_msglayout_sub *subs, UPB_NOINLINE const char *decode_isdonefallback(upb_decstate *d, const char *ptr, int overrun) { - ptr = decode_isdonefallback_inl(d, ptr, overrun); + int status; + ptr = decode_isdonefallback_inl(d, ptr, overrun, &status); if (ptr == NULL) { - return decode_err(d); + return decode_err(d, status); } return ptr; } static const char *decode_readstr(upb_decstate *d, const char *ptr, int size, upb_strview *str) { - if (d->alias) { + if (d->options & UPB_DECODE_ALIAS) { str->data = ptr; } else { char *data = upb_arena_malloc(&d->arena, size); - if (!data) return decode_err(d); + if (!data) return decode_err(d, UPB_DECODE_OOM); memcpy(data, ptr, size); str->data = data; } @@ -320,32 +321,39 @@ static const char *decode_readstr(upb_decstate *d, const char *ptr, int size, } UPB_FORCEINLINE -static const char *decode_tosubmsg(upb_decstate *d, const char *ptr, - upb_msg *submsg, - const upb_msglayout_sub *subs, - const upb_msglayout_field *field, int size) { - const upb_msglayout *subl = subs[field->submsg_index].submsg; +static const char *decode_tosubmsg2(upb_decstate *d, const char *ptr, + upb_msg *submsg, const upb_msglayout *subl, + int size) { int saved_delta = decode_pushlimit(d, ptr, size); - if (--d->depth < 0) return decode_err(d); + if (--d->depth < 0) return decode_err(d, UPB_DECODE_MALFORMED); if (!decode_isdone(d, &ptr)) { ptr = decode_msg(d, ptr, submsg, subl); } - if (d->end_group != DECODE_NOGROUP) return decode_err(d); + if (d->end_group != DECODE_NOGROUP) return decode_err(d, UPB_DECODE_MALFORMED); decode_poplimit(d, ptr, saved_delta); d->depth++; return ptr; } +UPB_FORCEINLINE +static const char *decode_tosubmsg(upb_decstate *d, const char *ptr, + upb_msg *submsg, + const upb_msglayout_sub *subs, + const upb_msglayout_field *field, int size) { + return decode_tosubmsg2(d, ptr, submsg, subs[field->submsg_index].submsg, + size); +} + UPB_FORCEINLINE static const char *decode_group(upb_decstate *d, const char *ptr, upb_msg *submsg, const upb_msglayout *subl, uint32_t number) { - if (--d->depth < 0) return decode_err(d); + if (--d->depth < 0) return decode_err(d, UPB_DECODE_MALFORMED); if (decode_isdone(d, &ptr)) { - return decode_err(d); + return decode_err(d, UPB_DECODE_MALFORMED); } ptr = decode_msg(d, ptr, submsg, subl); - if (d->end_group != number) return decode_err(d); + if (d->end_group != number) return decode_err(d, UPB_DECODE_MALFORMED); d->end_group = DECODE_NOGROUP; d->depth++; return ptr; @@ -390,7 +398,7 @@ static bool decode_checkenum_slow(upb_decstate *d, const char *ptr, upb_msg *msg end = encode_varint32(v, end); if (!_upb_msg_addunknown(msg, buf, end - buf, &d->arena)) { - decode_err(d); + decode_err(d, UPB_DECODE_OOM); } return false; @@ -430,7 +438,8 @@ static const char *decode_fixed_packed(upb_decstate *d, const char *ptr, int mask = (1 << lg2) - 1; size_t count = val->size >> lg2; if ((val->size & mask) != 0) { - return decode_err(d); /* Length isn't a round multiple of elem size. */ + // Length isn't a round multiple of elem size. + return decode_err(d, UPB_DECODE_MALFORMED); } decode_reserve(d, arr, count); void *mem = UPB_PTR_AT(_upb_array_ptr(arr), arr->len << lg2, void); @@ -504,7 +513,7 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr, } else { size_t lg2 = desctype_to_elem_size_lg2[field->descriptortype]; arr = _upb_array_new(&d->arena, 4, lg2); - if (!arr) return decode_err(d); + if (!arr) return decode_err(d, UPB_DECODE_OOM); *arrp = arr; } @@ -542,6 +551,7 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr, case OP_FIXPCK_LG2(3): return decode_fixed_packed(d, ptr, arr, val, field, op - OP_FIXPCK_LG2(0)); + return decode_err(d, UPB_DECODE_MALFORMED); case OP_VARPCK_LG2(0): case OP_VARPCK_LG2(2): case OP_VARPCK_LG2(3): @@ -652,6 +662,19 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg, } return ptr; +} + +UPB_FORCEINLINE +static bool decode_checkrequired(upb_decstate *d, const upb_msg *msg, + const upb_msglayout *l) { + if (UPB_LIKELY(!l->required_mask)) return false; + // if (UPB_UNLIKELY(l->required_mask & 1)) { + // return decode_checkrequired_slow(d, msg, l); + // } + uint64_t msg_head; + memcpy(&msg_head, msg, 8); + msg_head = _upb_be_swap64(msg_head); + return l->required_mask & ~msg_head; } UPB_FORCEINLINE @@ -813,7 +836,7 @@ static const char *decode_wireval(upb_decstate *d, const char *ptr, default: break; } - return decode_err(d); + return decode_err(d, UPB_DECODE_MALFORMED); } UPB_FORCEINLINE @@ -827,7 +850,7 @@ static const char *decode_known(upb_decstate *d, const char *ptr, upb_msg *msg, if (UPB_UNLIKELY(mode & _UPB_MODE_IS_EXTENSION)) { const upb_msglayout_ext *ext_layout = (const upb_msglayout_ext*)field; upb_msg_ext *ext = _upb_msg_getorcreateext(msg, ext_layout, &d->arena); - if (UPB_UNLIKELY(!ext)) return decode_err(d); + if (UPB_UNLIKELY(!ext)) return decode_err(d, UPB_DECODE_OOM); msg = &ext->data; subs = &ext->ext->sub; } @@ -847,21 +870,22 @@ static const char *decode_known(upb_decstate *d, const char *ptr, upb_msg *msg, UPB_FORCEINLINE static const char *decode_unknown(upb_decstate *d, const char *ptr, upb_msg *msg, int field_number, int wire_type, - wireval val, const char **field_start) { - if (field_number == 0) return decode_err(d); + wireval val) { + if (field_number == 0) return decode_err(d, UPB_DECODE_MALFORMED); if (wire_type == UPB_WIRE_TYPE_DELIMITED) ptr += val.size; if (msg) { if (wire_type == UPB_WIRE_TYPE_START_GROUP) { - d->unknown = *field_start; + const char *preserved_unknown = d->unknown; d->unknown_msg = msg; ptr = decode_group(d, ptr, NULL, NULL, field_number); d->unknown_msg = NULL; - *field_start = d->unknown; + d->unknown = preserved_unknown; + // XXX: pointer could have flipped during decoding the group, + // ptr - d->unknown below will be borked. } - if (!_upb_msg_addunknown(msg, *field_start, ptr - *field_start, - &d->arena)) { - return decode_err(d); + if (!_upb_msg_addunknown(msg, d->unknown, ptr - d->unknown, &d->arena)) { + return decode_err(d, UPB_DECODE_OOM); } } else if (wire_type == UPB_WIRE_TYPE_START_GROUP) { ptr = decode_group(d, ptr, NULL, NULL, field_number); @@ -878,11 +902,11 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, const upb_msglayout_field *field; int field_number; int wire_type; - const char *field_start = ptr; wireval val; int op; UPB_ASSERT(ptr < d->limit_ptr); + d->unknown = ptr; ptr = decode_tag(d, ptr, &tag); field_number = tag >> 3; wire_type = tag & 7; @@ -900,8 +924,7 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, } else { switch (op) { case OP_UNKNOWN: - ptr = decode_unknown(d, ptr, msg, field_number, wire_type, val, - &field_start); + ptr = decode_unknown(d, ptr, msg, field_number, wire_type, val); break; case OP_MSGSET_ITEM: ptr = decode_msgset(d, ptr, msg, layout); @@ -915,8 +938,14 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg, } } - if (decode_isdone(d, &ptr)) return ptr; - if (decode_tryfastdispatch(d, &ptr, msg, layout)) return ptr; + if (decode_isdone(d, &ptr) || + decode_tryfastdispatch(d, &ptr, msg, layout)) { + if (UPB_UNLIKELY(d->options & UPB_CHECK_REQUIRED) && + decode_checkrequired(d, msg, layout)) { + d->missing_required = true; + } + return ptr; + } } } @@ -928,34 +957,34 @@ const char *fastdecode_generic(struct upb_decstate *d, const char *ptr, return decode_msg(d, ptr, msg, decode_totablep(table)); } -static bool decode_top(struct upb_decstate *d, const char *buf, void *msg, - const upb_msglayout *l) { +static upb_decodestatus decode_top(struct upb_decstate *d, const char *buf, + void *msg, const upb_msglayout *l) { if (!decode_tryfastdispatch(d, &buf, msg, l)) { decode_msg(d, buf, msg, l); } - return d->end_group == DECODE_NOGROUP; + if (d->end_group != DECODE_NOGROUP) return UPB_DECODE_MALFORMED; + if (d->missing_required) return UPB_DECODE_MISSING_REQUIRED; + return UPB_DECODE_OK; } -bool _upb_decode(const char *buf, size_t size, void *msg, - const upb_msglayout *l, const upb_extreg *extreg, int options, - upb_arena *arena) { - bool ok; +upb_decodestatus _upb_decode(const char *buf, size_t size, void *msg, + const upb_msglayout *l, const upb_extreg *extreg, + int options, upb_arena *arena) { upb_decstate state; unsigned depth = (unsigned)options >> 16; if (size == 0) { - return true; + return UPB_DECODE_OK; } else if (size <= 16) { memset(&state.patch, 0, 32); memcpy(&state.patch, buf, size); buf = state.patch; state.end = buf + size; state.limit = 0; - state.alias = false; + options &= ~UPB_DECODE_ALIAS; // Can't alias patch buf. } else { state.end = buf + size - 16; state.limit = 16; - state.alias = options & UPB_DECODE_ALIAS; } state.extreg = extreg; @@ -963,21 +992,22 @@ bool _upb_decode(const char *buf, size_t size, void *msg, state.unknown_msg = NULL; state.depth = depth ? depth : 64; state.end_group = DECODE_NOGROUP; + state.options = (uint16_t)options; + state.missing_required = false; state.arena.head = arena->head; state.arena.last_size = arena->last_size; state.arena.cleanup_metadata = arena->cleanup_metadata; state.arena.parent = arena; - if (UPB_UNLIKELY(UPB_SETJMP(state.err))) { - ok = false; - } else { - ok = decode_top(&state, buf, msg, l); + upb_decodestatus status = UPB_SETJMP(state.err); + if (UPB_LIKELY(!status)) { + status = decode_top(&state, buf, msg, l); } arena->head.ptr = state.arena.head.ptr; arena->head.end = state.arena.head.end; arena->cleanup_metadata = state.arena.cleanup_metadata; - return ok; + return status; } #undef OP_UNKNOWN diff --git a/upb/decode.h b/upb/decode.h index 24008910c0..98bf884f3e 100644 --- a/upb/decode.h +++ b/upb/decode.h @@ -45,17 +45,46 @@ enum { /* If set, strings will alias the input buffer instead of copying into the * arena. */ UPB_DECODE_ALIAS = 1, + + /* If set, the parse will return failure if any message is missing any required + * fields when the message data ends. The parse will still continue, and the + * failure will only be reported at the end. + * + * IMPORTANT CAVEATS: + * + * 1. This can throw a false positive failure if an incomplete message is seen + * on the wire but is later completed when the sub-message occurs again. + * For this reason, a second pass is required to verify a failure, to be + * truly robust. + * + * 2. This can return a false success if you are decoding into a message that + * already has some sub-message fields present. If the sub-message does + * not occur in the binary payload, we will never visit it and discover the + * incomplete sub-message. For this reason, this check is only useful for + * implemting ParseFromString() semantics. For MergeFromString(), a + * post-parse validation step will always be necessary. */ + UPB_CHECK_REQUIRED = 2, }; #define UPB_DECODE_MAXDEPTH(depth) ((depth) << 16) -bool _upb_decode(const char *buf, size_t size, upb_msg *msg, - const upb_msglayout *l, const upb_extreg *extreg, int options, - upb_arena *arena); +typedef enum { + UPB_DECODE_OK = 0, + // UPB_CHECK_REQUIRED failed (see above), but the parse otherwise succeeded. + UPB_DECODE_MISSING_REQUIRED = 1, + UPB_DECODE_OOM = 2, // Arena alloc failed. + UPB_DECODE_BAD_UTF8 = 3, // String field had bad UTF-8. + UPB_DECODE_MAXDEPTH_EXCEEDED = 4, + UPB_DECODE_MALFORMED = 5, // Binary data was malformed. +} upb_decodestatus; + +upb_decodestatus _upb_decode(const char *buf, size_t size, upb_msg *msg, + const upb_msglayout *l, const upb_extreg *extreg, + int options, upb_arena *arena); UPB_INLINE -bool upb_decode(const char *buf, size_t size, upb_msg *msg, - const upb_msglayout *l, upb_arena *arena) { +upb_decodestatus upb_decode(const char *buf, size_t size, upb_msg *msg, + const upb_msglayout *l, upb_arena *arena) { return _upb_decode(buf, size, msg, l, NULL, 0, arena); } diff --git a/upb/decode_fast.c b/upb/decode_fast.c index d38136aa4c..5287bfdfba 100644 --- a/upb/decode_fast.c +++ b/upb/decode_fast.c @@ -68,9 +68,10 @@ typedef enum { UPB_NOINLINE static const char *fastdecode_isdonefallback(UPB_PARSE_PARAMS) { int overrun = data; - ptr = decode_isdonefallback_inl(d, ptr, overrun); + int status; + ptr = decode_isdonefallback_inl(d, ptr, overrun, &status); if (ptr == NULL) { - return fastdecode_err(d); + return fastdecode_err(d, status); } data = fastdecode_loadtag(ptr); UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); @@ -397,8 +398,7 @@ done: \ ptr += tagbytes; \ ptr = fastdecode_varint64(ptr, &val); \ - if (ptr == NULL) \ - return fastdecode_err(d); \ + if (ptr == NULL) return fastdecode_err(d, UPB_DECODE_MALFORMED); \ val = fastdecode_munge(val, valbytes, zigzag); \ memcpy(dst, &val, valbytes); \ \ @@ -406,14 +406,14 @@ done: fastdecode_nextret ret = fastdecode_nextrepeated( \ d, dst, &ptr, &farr, data, tagbytes, valbytes); \ switch (ret.next) { \ - case FD_NEXT_SAMEFIELD: \ - dst = ret.dst; \ - goto again; \ - case FD_NEXT_OTHERFIELD: \ - data = ret.tag; \ - UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ - case FD_NEXT_ATLIMIT: \ - return ptr; \ + case FD_NEXT_SAMEFIELD: \ + dst = ret.dst; \ + goto again; \ + case FD_NEXT_OTHERFIELD: \ + data = ret.tag; \ + UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ + case FD_NEXT_ATLIMIT: \ + return ptr; \ } \ } \ \ @@ -462,7 +462,7 @@ static const char *fastdecode_topackedvarint(upb_decstate *d, const char *ptr, ptr = fastdecode_delimited(d, ptr, &fastdecode_topackedvarint, &ctx); \ \ if (UPB_UNLIKELY(ptr == NULL)) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, UPB_DECODE_MALFORMED); \ } \ \ UPB_MUSTTAIL return fastdecode_dispatch(d, ptr, msg, table, hasbits, 0); @@ -579,7 +579,7 @@ TAGBYTES(p) \ if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr) || \ (size % valbytes) != 0)) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, UPB_DECODE_MALFORMED); \ } \ \ upb_array **arr_p = fastdecode_fieldmem(msg, data); \ @@ -590,7 +590,7 @@ TAGBYTES(p) if (UPB_LIKELY(!arr)) { \ *arr_p = arr = _upb_array_new(&d->arena, elems, elem_size_lg2); \ if (!arr) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, UPB_DECODE_MALFORMED); \ } \ } else { \ _upb_array_resize(arr, elems, &d->arena); \ @@ -656,7 +656,7 @@ static const char *fastdecode_verifyutf8(upb_decstate *d, const char *ptr, uint64_t hasbits, uint64_t data) { upb_strview *dst = (upb_strview*)data; if (!decode_verifyutf8_inl(dst->data, dst->size)) { - return fastdecode_err(d); + return fastdecode_err(d, UPB_DECODE_BAD_UTF8); } UPB_MUSTTAIL return fastdecode_dispatch(UPB_PARSE_ARGS); } @@ -670,16 +670,16 @@ static const char *fastdecode_verifyutf8(upb_decstate *d, const char *ptr, \ if (UPB_UNLIKELY(fastdecode_boundscheck(ptr, size, d->limit_ptr))) { \ dst->size = 0; \ - return fastdecode_err(d); \ + return fastdecode_err(d, UPB_DECODE_MALFORMED); \ } \ \ - if (d->alias) { \ + if (d->options & UPB_DECODE_ALIAS) { \ dst->data = ptr; \ dst->size = size; \ } else { \ char *data = upb_arena_malloc(&d->arena, size); \ if (!data) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, UPB_DECODE_OOM); \ } \ memcpy(data, ptr, size); \ dst->data = data; \ @@ -732,7 +732,7 @@ static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size, size_t common_has; \ char *buf; \ \ - UPB_ASSERT(!d->alias); \ + UPB_ASSERT((d->options & UPB_DECODE_ALIAS) == 0); \ UPB_ASSERT(fastdecode_checktag(data, tagbytes)); \ \ dst = fastdecode_getfield(d, ptr, msg, &data, &hasbits, &farr, \ @@ -752,22 +752,18 @@ static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size, common_has = UPB_MIN(arena_has, (d->end - ptr) + 16); \ \ if (UPB_LIKELY(size <= 15 - tagbytes)) { \ - if (arena_has < 16) \ - goto longstr; \ + if (arena_has < 16) goto longstr; \ d->arena.head.ptr += 16; \ memcpy(buf, ptr - tagbytes - 1, 16); \ dst->data = buf + tagbytes + 1; \ } else if (UPB_LIKELY(size <= 32)) { \ - if (UPB_UNLIKELY(common_has < 32)) \ - goto longstr; \ + if (UPB_UNLIKELY(common_has < 32)) goto longstr; \ fastdecode_docopy(d, ptr, size, 32, buf, dst); \ } else if (UPB_LIKELY(size <= 64)) { \ - if (UPB_UNLIKELY(common_has < 64)) \ - goto longstr; \ + if (UPB_UNLIKELY(common_has < 64)) goto longstr; \ fastdecode_docopy(d, ptr, size, 64, buf, dst); \ } else if (UPB_LIKELY(size < 128)) { \ - if (UPB_UNLIKELY(common_has < 128)) \ - goto longstr; \ + if (UPB_UNLIKELY(common_has < 128)) goto longstr; \ fastdecode_docopy(d, ptr, size, 128, buf, dst); \ } else { \ goto longstr; \ @@ -777,19 +773,19 @@ static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size, \ if (card == CARD_r) { \ if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, UPB_DECODE_BAD_UTF8); \ } \ fastdecode_nextret ret = fastdecode_nextrepeated( \ d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview)); \ switch (ret.next) { \ - case FD_NEXT_SAMEFIELD: \ - dst = ret.dst; \ - goto again; \ - case FD_NEXT_OTHERFIELD: \ - data = ret.tag; \ - UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ - case FD_NEXT_ATLIMIT: \ - return ptr; \ + case FD_NEXT_SAMEFIELD: \ + dst = ret.dst; \ + goto again; \ + case FD_NEXT_OTHERFIELD: \ + data = ret.tag; \ + UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ + case FD_NEXT_ATLIMIT: \ + return ptr; \ } \ } \ \ @@ -820,7 +816,7 @@ static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size, RETURN_GENERIC("string field tag mismatch\n"); \ } \ \ - if (UPB_UNLIKELY(!d->alias)) { \ + if (UPB_UNLIKELY((d->options & UPB_DECODE_ALIAS) == 0)) { \ UPB_MUSTTAIL return copyfunc(UPB_PARSE_ARGS); \ } \ \ @@ -852,27 +848,27 @@ static void fastdecode_docopy(upb_decstate *d, const char *ptr, uint32_t size, \ if (card == CARD_r) { \ if (validate_utf8 && !decode_verifyutf8_inl(dst->data, dst->size)) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, UPB_DECODE_BAD_UTF8); \ } \ fastdecode_nextret ret = fastdecode_nextrepeated( \ d, dst, &ptr, &farr, data, tagbytes, sizeof(upb_strview)); \ switch (ret.next) { \ - case FD_NEXT_SAMEFIELD: \ - dst = ret.dst; \ - if (UPB_UNLIKELY(!d->alias)) { \ - /* Buffer flipped and we can't alias any more. Bounce to */ \ - /* copyfunc(), but via dispatch since we need to reload table */ \ - /* data also. */ \ - fastdecode_commitarr(dst, &farr, sizeof(upb_strview)); \ + case FD_NEXT_SAMEFIELD: \ + dst = ret.dst; \ + if (UPB_UNLIKELY((d->options & UPB_DECODE_ALIAS) == 0)) { \ + /* Buffer flipped and we can't alias any more. Bounce to */ \ + /* copyfunc(), but via dispatch since we need to reload table */ \ + /* data also. */ \ + fastdecode_commitarr(dst, &farr, sizeof(upb_strview)); \ + data = ret.tag; \ + UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ + } \ + goto again; \ + case FD_NEXT_OTHERFIELD: \ data = ret.tag; \ UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ - } \ - goto again; \ - case FD_NEXT_OTHERFIELD: \ - data = ret.tag; \ - UPB_MUSTTAIL return fastdecode_tagdispatch(UPB_PARSE_ARGS); \ - case FD_NEXT_ATLIMIT: \ - return ptr; \ + case FD_NEXT_ATLIMIT: \ + return ptr; \ } \ } \ \ @@ -964,7 +960,9 @@ static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr, RETURN_GENERIC("submessage field tag mismatch\n"); \ } \ \ - if (--d->depth == 0) return fastdecode_err(d); \ + if (--d->depth == 0) { \ + return fastdecode_err(d, UPB_DECODE_MAXDEPTH_EXCEEDED); \ + } \ \ upb_msg **dst; \ uint32_t submsg_idx = (data >> 16) & 0xff; \ @@ -1000,7 +998,7 @@ static const char *fastdecode_tosubmsg(upb_decstate *d, const char *ptr, ptr = fastdecode_delimited(d, ptr, fastdecode_tosubmsg, &submsg); \ \ if (UPB_UNLIKELY(ptr == NULL || d->end_group != DECODE_NOGROUP)) { \ - return fastdecode_err(d); \ + return fastdecode_err(d, UPB_DECODE_MALFORMED); \ } \ \ if (card == CARD_r) { \ diff --git a/upb/decode_internal.h b/upb/decode_internal.h index 74003e4c95..2085ae465b 100644 --- a/upb/decode_internal.h +++ b/upb/decode_internal.h @@ -35,9 +35,10 @@ #include +#include "third_party/utf8_range/utf8_range.h" +#include "upb/decode.h" #include "upb/msg_internal.h" #include "upb/upb_internal.h" -#include "third_party/utf8_range/utf8_range.h" /* Must be last. */ #include "upb/port_def.inc" @@ -51,9 +52,10 @@ typedef struct upb_decstate { const char *unknown; /* Start of unknown data. */ const upb_extreg *extreg; /* For looking up extensions during the parse. */ int limit; /* Submessage limit relative to end. */ - int depth; + int depth; /* Tracks recursion depth to bound stack usage. */ uint32_t end_group; /* field number of END_GROUP tag, else DECODE_NOGROUP */ - bool alias; + uint16_t options; + bool missing_required; char patch[32]; upb_arena arena; jmp_buf err; @@ -66,7 +68,7 @@ typedef struct upb_decstate { * of our optimizations. That is also why we must declare it in a separate file, * otherwise the compiler will see that it calls longjmp() and deduce that it is * noreturn. */ -const char *fastdecode_err(upb_decstate *d); +const char *fastdecode_err(upb_decstate *d, int status); extern const uint8_t upb_utf8_offsets[]; @@ -106,13 +108,14 @@ UPB_INLINE const upb_msglayout *decode_totablep(intptr_t table) { UPB_INLINE const char *decode_isdonefallback_inl(upb_decstate *d, const char *ptr, - int overrun) { + int overrun, int *status) { if (overrun < d->limit) { /* Need to copy remaining data into patch buffer. */ UPB_ASSERT(overrun < 16); if (d->unknown_msg) { if (!_upb_msg_addunknown(d->unknown_msg, d->unknown, ptr - d->unknown, &d->arena)) { + *status = UPB_DECODE_OOM; return NULL; } d->unknown = &d->patch[0] + overrun; @@ -123,10 +126,11 @@ const char *decode_isdonefallback_inl(upb_decstate *d, const char *ptr, d->end = &d->patch[16]; d->limit -= 16; d->limit_ptr = d->end + d->limit; - d->alias = false; + d->options &= ~UPB_DECODE_ALIAS; UPB_ASSERT(ptr < d->limit_ptr); return ptr; } else { + *status = UPB_DECODE_MALFORMED; return NULL; } } diff --git a/upb/def.c b/upb/def.c index a2d533d614..b9f5dd745b 100644 --- a/upb/def.c +++ b/upb/def.c @@ -2200,7 +2200,7 @@ static void create_fielddef( if (ctx->symtab->allow_name_conflicts && deftype(existing_v) == UPB_DEFTYPE_FIELD_JSONNAME) { // Field name takes precedence over json name. - upb_strtable_remove(&m->ntof, shortname, strlen(shortname), NULL); + upb_strtable_remove2(&m->ntof, shortname, strlen(shortname), NULL); } else { symtab_errf(ctx, "duplicate field name (%s)", shortname); } diff --git a/upb/json_encode.c b/upb/json_encode.c index 6ec9c84251..3fd46b191f 100644 --- a/upb/json_encode.c +++ b/upb/json_encode.c @@ -374,7 +374,7 @@ static void jsonenc_any(jsonenc *e, const upb_msg *msg, const upb_msgdef *m) { upb_arena *arena = jsonenc_arena(e); upb_msg *any = upb_msg_new(any_m, arena); - if (!upb_decode(value.data, value.size, any, any_layout, arena)) { + if (upb_decode(value.data, value.size, any, any_layout, arena)) { jsonenc_err(e, "Error decoding message in Any"); } diff --git a/upb/msg.c b/upb/msg.c index 54426ec721..e96fd86c71 100644 --- a/upb/msg.c +++ b/upb/msg.c @@ -392,7 +392,7 @@ failure: for (end = e, e = start; e < end; e++) { const upb_msglayout_ext *ext = *e; extreg_key(buf, ext->extendee, ext->field.number); - upb_strtable_remove(&r->exts, buf, EXTREG_KEY_SIZE, NULL); + upb_strtable_remove2(&r->exts, buf, EXTREG_KEY_SIZE, NULL); } return false; } diff --git a/upb/msg_internal.h b/upb/msg_internal.h index 1fbb2c7182..2b6b580a35 100644 --- a/upb/msg_internal.h +++ b/upb/msg_internal.h @@ -56,13 +56,6 @@ extern "C" { * members are public so generated code can initialize them, but users MUST NOT * read or write any of its members. */ -/* These aren't real labels according to descriptor.proto, but in the table we - * use these for map/packed fields instead of UPB_LABEL_REPEATED. */ -enum { - _UPB_LABEL_MAP = 4, - _UPB_LABEL_PACKED = 7 /* Low 3 bits are common with UPB_LABEL_REPEATED. */ -}; - typedef struct { uint32_t number; uint16_t offset; @@ -136,6 +129,17 @@ typedef struct { int value_count; } upb_enumlayout; +UPB_INLINE bool _upb_enumlayout_checkval(const upb_enumlayout *e, int32_t val) { + uint32_t uval = (uint32_t)val; + if (uval < 64) return e->mask & (1 << uval); + // OPT: binary search long lists? + int n = e->value_count; + for (int i = 0; i < n; i++) { + if (e->values[i] == val) return true; + } + return false; +} + typedef union { const struct upb_msglayout *submsg; const upb_enumlayout *subenum; @@ -165,6 +169,7 @@ typedef enum { struct upb_msglayout { const upb_msglayout_sub *subs; const upb_msglayout_field *fields; + uint64_t required_mask; /* Must be aligned to sizeof(void*). Doesn't include internal members like * unknown fields, extension dict, pointer to msglayout, etc. */ uint16_t size; @@ -237,6 +242,7 @@ typedef struct { typedef struct { upb_msg_internaldata *internal; + /* Message data follows. */ } upb_msg_internal; /* Maps upb_fieldtype_t -> memory size. */ @@ -279,19 +285,24 @@ bool _upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, /* The internal representation of an extension is self-describing: it contains * enough information that we can serialize it to binary format without needing - * to look it up in a registry. */ + * to look it up in a upb_extreg. + * + * This representation allocates 16 bytes to data on 64-bit platforms. This is + * rather wasteful for scalars (in the extreme case of bool, it wastes 15 + * bytes). We accept this because we expect messages to be the most common + * extension type. */ typedef struct { const upb_msglayout_ext *ext; union { upb_strview str; void *ptr; - double dbl; char scalar_data[8]; } data; } upb_msg_ext; -/* Adds the given extension data to the given message. The returned extension will - * have its "ext" member initialized according to |ext|. */ +/* Adds the given extension data to the given message. |ext| is copied into the + * message instance. This logically replaces any previously-added extension with + * this number */ upb_msg_ext *_upb_msg_getorcreateext(upb_msg *msg, const upb_msglayout_ext *ext, upb_arena *arena); @@ -306,6 +317,8 @@ const upb_msg_ext *_upb_msg_getext(const upb_msg *msg, void _upb_msg_clearext(upb_msg *msg, const upb_msglayout_ext *ext); +void _upb_msg_clearext(upb_msg *msg, const upb_msglayout_ext *ext); + /** Hasbit access *************************************************************/ UPB_INLINE bool _upb_hasbit(const upb_msg *msg, size_t idx) { @@ -634,13 +647,13 @@ UPB_INLINE bool _upb_map_set(upb_map *map, const void *key, size_t key_size, if (!_upb_map_tovalue(val, val_size, &tabval, a)) return false; /* TODO(haberman): add overwrite operation to minimize number of lookups. */ - upb_strtable_remove(&map->table, strkey.data, strkey.size, NULL); + upb_strtable_remove2(&map->table, strkey.data, strkey.size, NULL); return upb_strtable_insert(&map->table, strkey.data, strkey.size, tabval, a); } UPB_INLINE bool _upb_map_delete(upb_map *map, const void *key, size_t key_size) { upb_strview k = _upb_map_tokey(key, key_size); - return upb_strtable_remove(&map->table, k.data, k.size, NULL); + return upb_strtable_remove2(&map->table, k.data, k.size, NULL); } UPB_INLINE void _upb_map_clear(upb_map *map) { diff --git a/upb/table.c b/upb/table.c index dabcff0482..63fecf27b2 100644 --- a/upb/table.c +++ b/upb/table.c @@ -516,8 +516,8 @@ bool upb_strtable_lookup2(const upb_strtable *t, const char *key, size_t len, return lookup(&t->t, strkey2(key, len), v, hash, &streql); } -bool upb_strtable_remove(upb_strtable *t, const char *key, size_t len, - upb_value *val) { +bool upb_strtable_remove2(upb_strtable *t, const char *key, size_t len, + upb_value *val) { uint32_t hash = table_hash(key, len); upb_tabkey tabkey; return rm(&t->t, strkey2(key, len), val, &tabkey, hash, &streql); @@ -812,7 +812,7 @@ bool upb_inttable_next2(const upb_inttable *t, uintptr_t *key, upb_value *val, while (++i < t->array_size) { upb_tabval ent = t->array[i]; if (upb_arrhas(ent)) { - *key = i; + *key = i; *val = _upb_value_val(ent.val); *iter = i; return true; diff --git a/upb/table_internal.h b/upb/table_internal.h index 11fa503052..fb0003e3d0 100644 --- a/upb/table_internal.h +++ b/upb/table_internal.h @@ -245,9 +245,14 @@ UPB_INLINE bool upb_strtable_lookup(const upb_strtable *t, const char *key, /* Removes an item from the table. Returns true if the remove was successful, * and stores the removed item in *val if non-NULL. */ bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val); -bool upb_strtable_remove(upb_strtable *t, const char *key, size_t len, +bool upb_strtable_remove2(upb_strtable *t, const char *key, size_t len, upb_value *val); +UPB_INLINE bool upb_strtable_remove(upb_strtable *t, const char *key, + upb_value *v) { + return upb_strtable_remove2(t, key, strlen(key), v); +} + /* Updates an existing entry in an inttable. If the entry does not exist, * returns false and does nothing. Unlike insert/remove, this does not * invalidate iterators. */ diff --git a/upbc/message_layout.cc b/upbc/message_layout.cc index 1c5cd0b167..1c71804ad5 100644 --- a/upbc/message_layout.cc +++ b/upbc/message_layout.cc @@ -166,18 +166,29 @@ void MessageLayout::PlaceNonOneofFields( }); // Place/count hasbits. - int hasbit_count = 0; + hasbit_count_ = 0; + required_mask_ = 0; for (auto field : FieldHotnessOrder(descriptor)) { if (HasHasbit(field)) { // We don't use hasbit 0, so that 0 can indicate "no presence" in the // table. This wastes one hasbit, but we don't worry about it for now. - hasbit_indexes_[field] = ++hasbit_count; + int index = ++hasbit_count_; + hasbit_indexes_[field] = index; + if (field->is_required()) { + if (index > 63) { + std::cerr << "upb does not support messages with more than 64 " + "required fields: " + << field->full_name() << "\n"; + exit(1); + } + required_mask_ |= 1 << index; + } } } // Place hasbits at the beginning. - int64_t hasbit_bytes = DivRoundUp(hasbit_count, 8); - Place(SizeAndAlign{{hasbit_bytes, hasbit_bytes}, {1, 1}}); + hasbit_bytes_ = DivRoundUp(hasbit_count_, 8); + Place(SizeAndAlign{{hasbit_bytes_, hasbit_bytes_}, {1, 1}}); // Place non-oneof fields. for (auto field : field_order) { diff --git a/upbc/message_layout.h b/upbc/message_layout.h index e4e5d74e64..9d4c1e249a 100644 --- a/upbc/message_layout.h +++ b/upbc/message_layout.h @@ -85,6 +85,10 @@ class MessageLayout { Size message_size() const { return size_; } + int hasbit_count() const { return hasbit_count_; } + int hasbit_bytes() const { return hasbit_bytes_; } + uint64_t required_mask() const { return required_mask_; } + static bool HasHasbit(const google::protobuf::FieldDescriptor* field); static SizeAndAlign SizeOfUnwrapped( const google::protobuf::FieldDescriptor* field); @@ -126,6 +130,9 @@ class MessageLayout { oneof_case_offsets_; Size maxalign_; Size size_; + int hasbit_count_; + int hasbit_bytes_; + uint64_t required_mask_; }; // Returns fields in order of "hotness", eg. how frequently they appear in @@ -140,7 +147,8 @@ inline std::vector FieldHotnessOrder( std::sort(fields.begin(), fields.end(), [](const google::protobuf::FieldDescriptor* a, const google::protobuf::FieldDescriptor* b) { - return a->number() < b->number(); + return std::make_pair(!a->is_required(), a->number()) < + std::make_pair(!b->is_required(), b->number()); }); return fields; } diff --git a/upbc/protoc-gen-upb.cc b/upbc/protoc-gen-upb.cc index 0b77713ffb..7a685e08d8 100644 --- a/upbc/protoc-gen-upb.cc +++ b/upbc/protoc-gen-upb.cc @@ -83,12 +83,6 @@ void AddEnums(const protobuf::Descriptor* message, } } -template -void SortDefs(std::vector* defs) { - std::sort(defs->begin(), defs->end(), - [](T a, T b) { return a->full_name() < b->full_name(); }); -} - std::vector SortedEnums( const protobuf::FileDescriptor* file) { std::vector enums; @@ -98,7 +92,6 @@ std::vector SortedEnums( for (int i = 0; i < file->message_type_count(); i++) { AddEnums(file->message_type(i), &enums); } - SortDefs(&enums); return enums; } @@ -294,6 +287,35 @@ std::string SizeRep(const protobuf::FieldDescriptor* field) { } } +bool HasNonZeroDefault(const protobuf::FieldDescriptor* field) { + switch (field->cpp_type()) { + case protobuf::FieldDescriptor::CPPTYPE_MESSAGE: + return false; + case protobuf::FieldDescriptor::CPPTYPE_STRING: + return !field->default_value_string().empty(); + case protobuf::FieldDescriptor::CPPTYPE_INT32: + return field->default_value_int32() != 0; + case protobuf::FieldDescriptor::CPPTYPE_INT64: + return field->default_value_int64() != 0; + case protobuf::FieldDescriptor::CPPTYPE_UINT32: + return field->default_value_uint32() != 0; + case protobuf::FieldDescriptor::CPPTYPE_UINT64: + return field->default_value_uint64() != 0; + case protobuf::FieldDescriptor::CPPTYPE_FLOAT: + return field->default_value_float() != 0; + case protobuf::FieldDescriptor::CPPTYPE_DOUBLE: + return field->default_value_double() != 0; + case protobuf::FieldDescriptor::CPPTYPE_BOOL: + return field->default_value_bool() != false; + case protobuf::FieldDescriptor::CPPTYPE_ENUM: + // Use a number instead of a symbolic name so that we don't require + // this enum's header to be included. + return field->default_value_enum()->number() != 0; + } + ABSL_ASSERT(false); + return "XXX"; +} + std::string FieldDefault(const protobuf::FieldDescriptor* field) { switch (field->cpp_type()) { case protobuf::FieldDescriptor::CPPTYPE_MESSAGE: @@ -396,7 +418,7 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output " upb_arena *arena) {\n" " $0 *ret = $0_new(arena);\n" " if (!ret) return NULL;\n" - " if (!upb_decode(buf, size, ret, &$1, arena)) return NULL;\n" + " if (upb_decode(buf, size, ret, &$1, arena)) return NULL;\n" " return ret;\n" "}\n" "UPB_INLINE $0 *$0_parse_ex(const char *buf, size_t size,\n" @@ -404,7 +426,7 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output " upb_arena *arena) {\n" " $0 *ret = $0_new(arena);\n" " if (!ret) return NULL;\n" - " if (!_upb_decode(buf, size, ret, &$1, extreg, options, arena)) {\n" + " if (_upb_decode(buf, size, ret, &$1, extreg, options, arena)) {\n" " return NULL;\n" " }\n" " return ret;\n" @@ -512,11 +534,19 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output GetSizeInit(layout.GetOneofCaseOffset(field->real_containing_oneof())), field->number(), FieldDefault(field)); } else { - output( - "UPB_INLINE $0 $1_$2(const $1 *msg) { " - "return *UPB_PTR_AT(msg, $3, $0); }\n", - CTypeConst(field), msg_name, field->name(), - GetSizeInit(layout.GetFieldOffset(field))); + if (HasNonZeroDefault(field)) { + output( + "UPB_INLINE $0 $1_$2(const $1 *msg) { " + "return $1_has_$2(msg) ? *UPB_PTR_AT(msg, $3, $0) : $4; }\n", + CTypeConst(field), msg_name, field->name(), + GetSizeInit(layout.GetFieldOffset(field)), FieldDefault(field)); + } else { + output( + "UPB_INLINE $0 $1_$2(const $1 *msg) { " + "return *UPB_PTR_AT(msg, $3, $0); }\n", + CTypeConst(field), msg_name, field->name(), + GetSizeInit(layout.GetFieldOffset(field))); + } } } @@ -1144,6 +1174,7 @@ void WriteMessage(const protobuf::Descriptor* message, Output& output, std::string msg_name = ToCIdent(message->full_name()); std::string fields_array_ref = "NULL"; std::string submsgs_array_ref = "NULL"; + std::string subenums_array_ref = "NULL"; uint8_t dense_below = 0; const int dense_below_max = std::numeric_limits::max(); MessageLayout layout(message); @@ -1221,7 +1252,8 @@ void WriteMessage(const protobuf::Descriptor* message, Output& output, output("const upb_msglayout $0 = {\n", MessageInit(message)); output(" $0,\n", submsgs_array_ref); output(" $0,\n", fields_array_ref); - output(" $0, $1, $2, $3, $4,\n", + output(" $0, $1, $2, $3, $4, $5,\n", + layout.required_mask(), GetSizeInit(layout.message_size()), field_number_order.size(), msgext, @@ -1294,19 +1326,6 @@ int WriteEnums(const protobuf::FileDescriptor* file, Output& output) { return this_file_enums.size(); } -void WriteExtension(const protobuf::FieldDescriptor* ext, Output& output) { - output("const upb_msglayout_ext $0 = {\n ", ExtensionLayout(ext)); - WriteField(ext, "0", "0", 0, output); - output(",\n"); - output(" &$0,\n", MessageInit(ext->containing_type())); - if (ext->message_type()) { - output(" {.submsg = &$0},\n", MessageInit(ext->message_type())); - } else { - output(" {.submsg = NULL},\n"); - } - output("\n};\n"); -} - int WriteMessages(const protobuf::FileDescriptor* file, Output& output, bool fasttable_enabled) { std::vector file_messages = @@ -1328,6 +1347,21 @@ int WriteMessages(const protobuf::FileDescriptor* file, Output& output, return file_messages.size(); } +void WriteExtension(const protobuf::FieldDescriptor* ext, Output& output) { + output("const upb_msglayout_ext $0 = {\n ", ExtensionLayout(ext)); + WriteField(ext, "0", "0", 0, output); + output(",\n"); + output(" &$0,\n", MessageInit(ext->containing_type())); + if (ext->message_type()) { + output(" {.submsg = &$0},\n", MessageInit(ext->message_type())); + } else if (ext->enum_type() && ext->enum_type()->file()->syntax() == protobuf::FileDescriptor::SYNTAX_PROTO2) { + output(" {.subenum = &$0},\n", EnumInit(ext->enum_type())); + } else { + output(" {.submsg = NULL},\n"); + } + output("\n};\n"); +} + int WriteExtensions(const protobuf::FileDescriptor* file, Output& output) { auto exts = SortedExtensions(file); absl::flat_hash_set forward_decls;