Added support for extensions.

pull/13171/head
Joshua Haberman 4 years ago
parent 3f7c69ab7b
commit ce012b7b55
  1. 21
      BUILD
  2. 6
      README.md
  3. 457
      cmake/google/protobuf/descriptor.upb.c
  4. 2
      cmake/google/protobuf/descriptor.upb.h
  5. 1
      tests/conformance_upb_failures.txt
  6. 96
      upb/decode.c
  7. 1
      upb/decode_internal.h
  8. 247
      upb/def.c
  9. 20
      upb/def.h
  10. 119
      upb/encode.c
  11. 23
      upb/json_decode.c
  12. 2
      upb/json_decode.h
  13. 16
      upb/json_encode.c
  14. 31
      upb/msg.c
  15. 78
      upb/msg_internal.h
  16. 156
      upb/reflection.c
  17. 3
      upb/reflection.h
  18. 1
      upbc/BUILD
  19. 25
      upbc/common.cc
  20. 5
      upbc/common.h
  21. 259
      upbc/protoc-gen-upb.cc
  22. 24
      upbc/protoc-gen-upbdefs.cc

21
BUILD

@ -215,6 +215,27 @@ cc_library(
],
)
cc_test(
name = "msg_test",
srcs = ["upb/msg_test.cc"],
deps = [
"@com_google_googletest//:gtest_main",
":msg_test_upb_proto_reflection",
":json",
],
)
proto_library(
name = "msg_test_proto",
srcs = ["upb/msg_test.proto"],
deps = ["@com_google_protobuf//:test_messages_proto3_proto"],
)
upb_proto_reflection_library(
name = "msg_test_upb_proto_reflection",
deps = [":msg_test_proto"],
)
# Internal C/C++ libraries #####################################################
cc_library(

@ -25,7 +25,8 @@ Like the main protobuf implementation in C++, it supports:
- reflection
- binary & JSON wire formats
- text format serialization
- all standard features of protobufs (oneofs, maps, unknown fields, etc.)
- all standard features of protobufs (oneofs, maps, unknown fields, extensions,
etc.)
- full conformance with the protobuf conformance tests
upb also supports some features that C++ does not:
@ -36,9 +37,8 @@ upb also supports some features that C++ does not:
- **fast reflection-based parsing:** messages loaded at runtime parse
just as fast as compiled-in messages.
However there are some features it does not support:
However there are a few features it does not support:
- proto2 extensions (coming soon!)
- text format parsing
- deep descriptor verification: upb's descriptor validation is not as exhaustive
as `protoc`.

@ -12,474 +12,511 @@
#include "upb/port_def.inc"
static const upb_msglayout *const google_protobuf_FileDescriptorSet_submsgs[1] = {
&google_protobuf_FileDescriptorProto_msginit,
static const upb_msglayout_sub google_protobuf_FileDescriptorSet_submsgs[1] = {
{.submsg = &google_protobuf_FileDescriptorProto_msginit},
};
static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] = {
{1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
{1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_FileDescriptorSet_msginit = {
&google_protobuf_FileDescriptorSet_submsgs[0],
&google_protobuf_FileDescriptorSet__fields[0],
UPB_SIZE(8, 8), 1, false, 1, 255,
UPB_SIZE(8, 8), 1, _UPB_MSGEXT_NONE, 1, 255,
};
static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6] = {
&google_protobuf_DescriptorProto_msginit,
&google_protobuf_EnumDescriptorProto_msginit,
&google_protobuf_FieldDescriptorProto_msginit,
&google_protobuf_FileOptions_msginit,
&google_protobuf_ServiceDescriptorProto_msginit,
&google_protobuf_SourceCodeInfo_msginit,
static const upb_msglayout_sub google_protobuf_FileDescriptorProto_submsgs[6] = {
{.submsg = &google_protobuf_DescriptorProto_msginit},
{.submsg = &google_protobuf_EnumDescriptorProto_msginit},
{.submsg = &google_protobuf_FieldDescriptorProto_msginit},
{.submsg = &google_protobuf_FileOptions_msginit},
{.submsg = &google_protobuf_ServiceDescriptorProto_msginit},
{.submsg = &google_protobuf_SourceCodeInfo_msginit},
};
static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12] = {
{1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
{2, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR},
{3, UPB_SIZE(36, 72), 0, 0, 12, _UPB_MODE_ARRAY},
{4, UPB_SIZE(40, 80), 0, 0, 11, _UPB_MODE_ARRAY},
{5, UPB_SIZE(44, 88), 0, 1, 11, _UPB_MODE_ARRAY},
{6, UPB_SIZE(48, 96), 0, 4, 11, _UPB_MODE_ARRAY},
{7, UPB_SIZE(52, 104), 0, 2, 11, _UPB_MODE_ARRAY},
{8, UPB_SIZE(28, 56), 3, 3, 11, _UPB_MODE_SCALAR},
{9, UPB_SIZE(32, 64), 4, 5, 11, _UPB_MODE_SCALAR},
{10, UPB_SIZE(56, 112), 0, 0, 5, _UPB_MODE_ARRAY},
{11, UPB_SIZE(60, 120), 0, 0, 5, _UPB_MODE_ARRAY},
{12, UPB_SIZE(20, 40), 5, 0, 12, _UPB_MODE_SCALAR},
{1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{2, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{3, UPB_SIZE(36, 72), 0, 0, 12, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{4, UPB_SIZE(40, 80), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{5, UPB_SIZE(44, 88), 0, 1, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{6, UPB_SIZE(48, 96), 0, 4, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{7, UPB_SIZE(52, 104), 0, 2, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{8, UPB_SIZE(28, 56), 3, 3, 11, _UPB_MODE_SCALAR | (_UPB_REP_PTR << 6)},
{9, UPB_SIZE(32, 64), 4, 5, 11, _UPB_MODE_SCALAR | (_UPB_REP_PTR << 6)},
{10, UPB_SIZE(56, 112), 0, 0, 5, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{11, UPB_SIZE(60, 120), 0, 0, 5, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{12, UPB_SIZE(20, 40), 5, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
};
const upb_msglayout google_protobuf_FileDescriptorProto_msginit = {
&google_protobuf_FileDescriptorProto_submsgs[0],
&google_protobuf_FileDescriptorProto__fields[0],
UPB_SIZE(64, 128), 12, false, 12, 255,
UPB_SIZE(64, 128), 12, _UPB_MSGEXT_NONE, 12, 255,
};
static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[7] = {
&google_protobuf_DescriptorProto_msginit,
&google_protobuf_DescriptorProto_ExtensionRange_msginit,
&google_protobuf_DescriptorProto_ReservedRange_msginit,
&google_protobuf_EnumDescriptorProto_msginit,
&google_protobuf_FieldDescriptorProto_msginit,
&google_protobuf_MessageOptions_msginit,
&google_protobuf_OneofDescriptorProto_msginit,
static const upb_msglayout_sub google_protobuf_DescriptorProto_submsgs[7] = {
{.submsg = &google_protobuf_DescriptorProto_msginit},
{.submsg = &google_protobuf_DescriptorProto_ExtensionRange_msginit},
{.submsg = &google_protobuf_DescriptorProto_ReservedRange_msginit},
{.submsg = &google_protobuf_EnumDescriptorProto_msginit},
{.submsg = &google_protobuf_FieldDescriptorProto_msginit},
{.submsg = &google_protobuf_MessageOptions_msginit},
{.submsg = &google_protobuf_OneofDescriptorProto_msginit},
};
static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = {
{1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
{2, UPB_SIZE(16, 32), 0, 4, 11, _UPB_MODE_ARRAY},
{3, UPB_SIZE(20, 40), 0, 0, 11, _UPB_MODE_ARRAY},
{4, UPB_SIZE(24, 48), 0, 3, 11, _UPB_MODE_ARRAY},
{5, UPB_SIZE(28, 56), 0, 1, 11, _UPB_MODE_ARRAY},
{6, UPB_SIZE(32, 64), 0, 4, 11, _UPB_MODE_ARRAY},
{7, UPB_SIZE(12, 24), 2, 5, 11, _UPB_MODE_SCALAR},
{8, UPB_SIZE(36, 72), 0, 6, 11, _UPB_MODE_ARRAY},
{9, UPB_SIZE(40, 80), 0, 2, 11, _UPB_MODE_ARRAY},
{10, UPB_SIZE(44, 88), 0, 0, 12, _UPB_MODE_ARRAY},
{1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{2, UPB_SIZE(16, 32), 0, 4, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{3, UPB_SIZE(20, 40), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{4, UPB_SIZE(24, 48), 0, 3, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{5, UPB_SIZE(28, 56), 0, 1, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{6, UPB_SIZE(32, 64), 0, 4, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{7, UPB_SIZE(12, 24), 2, 5, 11, _UPB_MODE_SCALAR | (_UPB_REP_PTR << 6)},
{8, UPB_SIZE(36, 72), 0, 6, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{9, UPB_SIZE(40, 80), 0, 2, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{10, UPB_SIZE(44, 88), 0, 0, 12, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_DescriptorProto_msginit = {
&google_protobuf_DescriptorProto_submsgs[0],
&google_protobuf_DescriptorProto__fields[0],
UPB_SIZE(48, 96), 10, false, 10, 255,
UPB_SIZE(48, 96), 10, _UPB_MSGEXT_NONE, 10, 255,
};
static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = {
&google_protobuf_ExtensionRangeOptions_msginit,
static const upb_msglayout_sub google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = {
{.submsg = &google_protobuf_ExtensionRangeOptions_msginit},
};
static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange__fields[3] = {
{1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR},
{2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR},
{3, UPB_SIZE(12, 16), 3, 0, 11, _UPB_MODE_SCALAR},
{1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
{2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
{3, UPB_SIZE(12, 16), 3, 0, 11, _UPB_MODE_SCALAR | (_UPB_REP_PTR << 6)},
};
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, false, 3, 255,
UPB_SIZE(16, 24), 3, _UPB_MSGEXT_NONE, 3, 255,
};
static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2] = {
{1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR},
{2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR},
{1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
{2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
};
const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = {
NULL,
&google_protobuf_DescriptorProto_ReservedRange__fields[0],
UPB_SIZE(16, 16), 2, false, 2, 255,
UPB_SIZE(16, 16), 2, _UPB_MSGEXT_NONE, 2, 255,
};
static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1] = {
&google_protobuf_UninterpretedOption_msginit,
static const upb_msglayout_sub google_protobuf_ExtensionRangeOptions_submsgs[1] = {
{.submsg = &google_protobuf_UninterpretedOption_msginit},
};
static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1] = {
{999, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
{999, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = {
&google_protobuf_ExtensionRangeOptions_submsgs[0],
&google_protobuf_ExtensionRangeOptions__fields[0],
UPB_SIZE(8, 8), 1, false, 0, 255,
UPB_SIZE(8, 8), 1, _UPB_MSGEXT_EXTENDABLE, 0, 255,
};
static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1] = {
&google_protobuf_FieldOptions_msginit,
static const upb_msglayout_sub google_protobuf_FieldDescriptorProto_submsgs[1] = {
{.submsg = &google_protobuf_FieldOptions_msginit},
};
static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[11] = {
{1, UPB_SIZE(24, 24), 1, 0, 12, _UPB_MODE_SCALAR},
{2, UPB_SIZE(32, 40), 2, 0, 12, _UPB_MODE_SCALAR},
{3, UPB_SIZE(12, 12), 3, 0, 5, _UPB_MODE_SCALAR},
{4, UPB_SIZE(4, 4), 4, 0, 14, _UPB_MODE_SCALAR},
{5, UPB_SIZE(8, 8), 5, 0, 14, _UPB_MODE_SCALAR},
{6, UPB_SIZE(40, 56), 6, 0, 12, _UPB_MODE_SCALAR},
{7, UPB_SIZE(48, 72), 7, 0, 12, _UPB_MODE_SCALAR},
{8, UPB_SIZE(64, 104), 8, 0, 11, _UPB_MODE_SCALAR},
{9, UPB_SIZE(16, 16), 9, 0, 5, _UPB_MODE_SCALAR},
{10, UPB_SIZE(56, 88), 10, 0, 12, _UPB_MODE_SCALAR},
{17, UPB_SIZE(20, 20), 11, 0, 8, _UPB_MODE_SCALAR},
{1, UPB_SIZE(24, 24), 1, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{2, UPB_SIZE(32, 40), 2, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{3, UPB_SIZE(12, 12), 3, 0, 5, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
{4, UPB_SIZE(4, 4), 4, 0, 14, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
{5, UPB_SIZE(8, 8), 5, 0, 14, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
{6, UPB_SIZE(40, 56), 6, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{7, UPB_SIZE(48, 72), 7, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{8, UPB_SIZE(64, 104), 8, 0, 11, _UPB_MODE_SCALAR | (_UPB_REP_PTR << 6)},
{9, UPB_SIZE(16, 16), 9, 0, 5, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
{10, UPB_SIZE(56, 88), 10, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{17, UPB_SIZE(20, 20), 11, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
};
const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = {
&google_protobuf_FieldDescriptorProto_submsgs[0],
&google_protobuf_FieldDescriptorProto__fields[0],
UPB_SIZE(72, 112), 11, false, 10, 255,
UPB_SIZE(72, 112), 11, _UPB_MSGEXT_NONE, 10, 255,
};
static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = {
&google_protobuf_OneofOptions_msginit,
static const upb_msglayout_sub google_protobuf_OneofDescriptorProto_submsgs[1] = {
{.submsg = &google_protobuf_OneofOptions_msginit},
};
static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2] = {
{1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
{2, UPB_SIZE(12, 24), 2, 0, 11, _UPB_MODE_SCALAR},
{1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{2, UPB_SIZE(12, 24), 2, 0, 11, _UPB_MODE_SCALAR | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = {
&google_protobuf_OneofDescriptorProto_submsgs[0],
&google_protobuf_OneofDescriptorProto__fields[0],
UPB_SIZE(16, 32), 2, false, 2, 255,
UPB_SIZE(16, 32), 2, _UPB_MSGEXT_NONE, 2, 255,
};
static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3] = {
&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit,
&google_protobuf_EnumOptions_msginit,
&google_protobuf_EnumValueDescriptorProto_msginit,
static const upb_msglayout_sub google_protobuf_EnumDescriptorProto_submsgs[3] = {
{.submsg = &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit},
{.submsg = &google_protobuf_EnumOptions_msginit},
{.submsg = &google_protobuf_EnumValueDescriptorProto_msginit},
};
static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5] = {
{1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
{2, UPB_SIZE(16, 32), 0, 2, 11, _UPB_MODE_ARRAY},
{3, UPB_SIZE(12, 24), 2, 1, 11, _UPB_MODE_SCALAR},
{4, UPB_SIZE(20, 40), 0, 0, 11, _UPB_MODE_ARRAY},
{5, UPB_SIZE(24, 48), 0, 0, 12, _UPB_MODE_ARRAY},
{1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{2, UPB_SIZE(16, 32), 0, 2, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{3, UPB_SIZE(12, 24), 2, 1, 11, _UPB_MODE_SCALAR | (_UPB_REP_PTR << 6)},
{4, UPB_SIZE(20, 40), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{5, UPB_SIZE(24, 48), 0, 0, 12, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = {
&google_protobuf_EnumDescriptorProto_submsgs[0],
&google_protobuf_EnumDescriptorProto__fields[0],
UPB_SIZE(32, 64), 5, false, 5, 255,
UPB_SIZE(32, 64), 5, _UPB_MSGEXT_NONE, 5, 255,
};
static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = {
{1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR},
{2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR},
{1, UPB_SIZE(4, 4), 1, 0, 5, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
{2, UPB_SIZE(8, 8), 2, 0, 5, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
};
const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = {
NULL,
&google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0],
UPB_SIZE(16, 16), 2, false, 2, 255,
UPB_SIZE(16, 16), 2, _UPB_MSGEXT_NONE, 2, 255,
};
static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1] = {
&google_protobuf_EnumValueOptions_msginit,
static const upb_msglayout_sub google_protobuf_EnumValueDescriptorProto_submsgs[1] = {
{.submsg = &google_protobuf_EnumValueOptions_msginit},
};
static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = {
{1, UPB_SIZE(8, 8), 1, 0, 12, _UPB_MODE_SCALAR},
{2, UPB_SIZE(4, 4), 2, 0, 5, _UPB_MODE_SCALAR},
{3, UPB_SIZE(16, 24), 3, 0, 11, _UPB_MODE_SCALAR},
{1, UPB_SIZE(8, 8), 1, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{2, UPB_SIZE(4, 4), 2, 0, 5, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
{3, UPB_SIZE(16, 24), 3, 0, 11, _UPB_MODE_SCALAR | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = {
&google_protobuf_EnumValueDescriptorProto_submsgs[0],
&google_protobuf_EnumValueDescriptorProto__fields[0],
UPB_SIZE(24, 32), 3, false, 3, 255,
UPB_SIZE(24, 32), 3, _UPB_MSGEXT_NONE, 3, 255,
};
static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2] = {
&google_protobuf_MethodDescriptorProto_msginit,
&google_protobuf_ServiceOptions_msginit,
static const upb_msglayout_sub google_protobuf_ServiceDescriptorProto_submsgs[2] = {
{.submsg = &google_protobuf_MethodDescriptorProto_msginit},
{.submsg = &google_protobuf_ServiceOptions_msginit},
};
static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[3] = {
{1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
{2, UPB_SIZE(16, 32), 0, 0, 11, _UPB_MODE_ARRAY},
{3, UPB_SIZE(12, 24), 2, 1, 11, _UPB_MODE_SCALAR},
{1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{2, UPB_SIZE(16, 32), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{3, UPB_SIZE(12, 24), 2, 1, 11, _UPB_MODE_SCALAR | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = {
&google_protobuf_ServiceDescriptorProto_submsgs[0],
&google_protobuf_ServiceDescriptorProto__fields[0],
UPB_SIZE(24, 48), 3, false, 3, 255,
UPB_SIZE(24, 48), 3, _UPB_MSGEXT_NONE, 3, 255,
};
static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1] = {
&google_protobuf_MethodOptions_msginit,
static const upb_msglayout_sub google_protobuf_MethodDescriptorProto_submsgs[1] = {
{.submsg = &google_protobuf_MethodOptions_msginit},
};
static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = {
{1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
{2, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR},
{3, UPB_SIZE(20, 40), 3, 0, 12, _UPB_MODE_SCALAR},
{4, UPB_SIZE(28, 56), 4, 0, 11, _UPB_MODE_SCALAR},
{5, UPB_SIZE(1, 1), 5, 0, 8, _UPB_MODE_SCALAR},
{6, UPB_SIZE(2, 2), 6, 0, 8, _UPB_MODE_SCALAR},
{1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{2, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{3, UPB_SIZE(20, 40), 3, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{4, UPB_SIZE(28, 56), 4, 0, 11, _UPB_MODE_SCALAR | (_UPB_REP_PTR << 6)},
{5, UPB_SIZE(1, 1), 5, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{6, UPB_SIZE(2, 2), 6, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
};
const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = {
&google_protobuf_MethodDescriptorProto_submsgs[0],
&google_protobuf_MethodDescriptorProto__fields[0],
UPB_SIZE(32, 64), 6, false, 6, 255,
UPB_SIZE(32, 64), 6, _UPB_MSGEXT_NONE, 6, 255,
};
static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = {
&google_protobuf_UninterpretedOption_msginit,
static const upb_msglayout_sub google_protobuf_FileOptions_submsgs[1] = {
{.submsg = &google_protobuf_UninterpretedOption_msginit},
};
static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = {
{1, UPB_SIZE(20, 24), 1, 0, 12, _UPB_MODE_SCALAR},
{8, UPB_SIZE(28, 40), 2, 0, 12, _UPB_MODE_SCALAR},
{9, UPB_SIZE(4, 4), 3, 0, 14, _UPB_MODE_SCALAR},
{10, UPB_SIZE(8, 8), 4, 0, 8, _UPB_MODE_SCALAR},
{11, UPB_SIZE(36, 56), 5, 0, 12, _UPB_MODE_SCALAR},
{16, UPB_SIZE(9, 9), 6, 0, 8, _UPB_MODE_SCALAR},
{17, UPB_SIZE(10, 10), 7, 0, 8, _UPB_MODE_SCALAR},
{18, UPB_SIZE(11, 11), 8, 0, 8, _UPB_MODE_SCALAR},
{20, UPB_SIZE(12, 12), 9, 0, 8, _UPB_MODE_SCALAR},
{23, UPB_SIZE(13, 13), 10, 0, 8, _UPB_MODE_SCALAR},
{27, UPB_SIZE(14, 14), 11, 0, 8, _UPB_MODE_SCALAR},
{31, UPB_SIZE(15, 15), 12, 0, 8, _UPB_MODE_SCALAR},
{36, UPB_SIZE(44, 72), 13, 0, 12, _UPB_MODE_SCALAR},
{37, UPB_SIZE(52, 88), 14, 0, 12, _UPB_MODE_SCALAR},
{39, UPB_SIZE(60, 104), 15, 0, 12, _UPB_MODE_SCALAR},
{40, UPB_SIZE(68, 120), 16, 0, 12, _UPB_MODE_SCALAR},
{41, UPB_SIZE(76, 136), 17, 0, 12, _UPB_MODE_SCALAR},
{42, UPB_SIZE(16, 16), 18, 0, 8, _UPB_MODE_SCALAR},
{44, UPB_SIZE(84, 152), 19, 0, 12, _UPB_MODE_SCALAR},
{45, UPB_SIZE(92, 168), 20, 0, 12, _UPB_MODE_SCALAR},
{999, UPB_SIZE(100, 184), 0, 0, 11, _UPB_MODE_ARRAY},
{1, UPB_SIZE(20, 24), 1, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{8, UPB_SIZE(28, 40), 2, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{9, UPB_SIZE(4, 4), 3, 0, 14, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
{10, UPB_SIZE(8, 8), 4, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{11, UPB_SIZE(36, 56), 5, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{16, UPB_SIZE(9, 9), 6, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{17, UPB_SIZE(10, 10), 7, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{18, UPB_SIZE(11, 11), 8, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{20, UPB_SIZE(12, 12), 9, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{23, UPB_SIZE(13, 13), 10, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{27, UPB_SIZE(14, 14), 11, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{31, UPB_SIZE(15, 15), 12, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{36, UPB_SIZE(44, 72), 13, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{37, UPB_SIZE(52, 88), 14, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{39, UPB_SIZE(60, 104), 15, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{40, UPB_SIZE(68, 120), 16, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{41, UPB_SIZE(76, 136), 17, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{42, UPB_SIZE(16, 16), 18, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{44, UPB_SIZE(84, 152), 19, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{45, UPB_SIZE(92, 168), 20, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{999, UPB_SIZE(100, 184), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_FileOptions_msginit = {
&google_protobuf_FileOptions_submsgs[0],
&google_protobuf_FileOptions__fields[0],
UPB_SIZE(104, 192), 21, false, 1, 255,
UPB_SIZE(104, 192), 21, _UPB_MSGEXT_EXTENDABLE, 1, 255,
};
static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = {
&google_protobuf_UninterpretedOption_msginit,
static const upb_msglayout_sub google_protobuf_MessageOptions_submsgs[1] = {
{.submsg = &google_protobuf_UninterpretedOption_msginit},
};
static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = {
{1, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR},
{2, UPB_SIZE(2, 2), 2, 0, 8, _UPB_MODE_SCALAR},
{3, UPB_SIZE(3, 3), 3, 0, 8, _UPB_MODE_SCALAR},
{7, UPB_SIZE(4, 4), 4, 0, 8, _UPB_MODE_SCALAR},
{999, UPB_SIZE(8, 8), 0, 0, 11, _UPB_MODE_ARRAY},
{1, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{2, UPB_SIZE(2, 2), 2, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{3, UPB_SIZE(3, 3), 3, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{7, UPB_SIZE(4, 4), 4, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{999, UPB_SIZE(8, 8), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_MessageOptions_msginit = {
&google_protobuf_MessageOptions_submsgs[0],
&google_protobuf_MessageOptions__fields[0],
UPB_SIZE(16, 16), 5, false, 3, 255,
UPB_SIZE(16, 16), 5, _UPB_MSGEXT_EXTENDABLE, 3, 255,
};
static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = {
&google_protobuf_UninterpretedOption_msginit,
static const upb_msglayout_sub google_protobuf_FieldOptions_submsgs[1] = {
{.submsg = &google_protobuf_UninterpretedOption_msginit},
};
static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = {
{1, UPB_SIZE(4, 4), 1, 0, 14, _UPB_MODE_SCALAR},
{2, UPB_SIZE(12, 12), 2, 0, 8, _UPB_MODE_SCALAR},
{3, UPB_SIZE(13, 13), 3, 0, 8, _UPB_MODE_SCALAR},
{5, UPB_SIZE(14, 14), 4, 0, 8, _UPB_MODE_SCALAR},
{6, UPB_SIZE(8, 8), 5, 0, 14, _UPB_MODE_SCALAR},
{10, UPB_SIZE(15, 15), 6, 0, 8, _UPB_MODE_SCALAR},
{999, UPB_SIZE(16, 16), 0, 0, 11, _UPB_MODE_ARRAY},
{1, UPB_SIZE(4, 4), 1, 0, 14, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
{2, UPB_SIZE(12, 12), 2, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{3, UPB_SIZE(13, 13), 3, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{5, UPB_SIZE(14, 14), 4, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{6, UPB_SIZE(8, 8), 5, 0, 14, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
{10, UPB_SIZE(15, 15), 6, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{999, UPB_SIZE(16, 16), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_FieldOptions_msginit = {
&google_protobuf_FieldOptions_submsgs[0],
&google_protobuf_FieldOptions__fields[0],
UPB_SIZE(24, 24), 7, false, 3, 255,
UPB_SIZE(24, 24), 7, _UPB_MSGEXT_EXTENDABLE, 3, 255,
};
static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = {
&google_protobuf_UninterpretedOption_msginit,
static const upb_msglayout_sub google_protobuf_OneofOptions_submsgs[1] = {
{.submsg = &google_protobuf_UninterpretedOption_msginit},
};
static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = {
{999, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
{999, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_OneofOptions_msginit = {
&google_protobuf_OneofOptions_submsgs[0],
&google_protobuf_OneofOptions__fields[0],
UPB_SIZE(8, 8), 1, false, 0, 255,
UPB_SIZE(8, 8), 1, _UPB_MSGEXT_EXTENDABLE, 0, 255,
};
static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = {
&google_protobuf_UninterpretedOption_msginit,
static const upb_msglayout_sub google_protobuf_EnumOptions_submsgs[1] = {
{.submsg = &google_protobuf_UninterpretedOption_msginit},
};
static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = {
{2, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR},
{3, UPB_SIZE(2, 2), 2, 0, 8, _UPB_MODE_SCALAR},
{999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY},
{2, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{3, UPB_SIZE(2, 2), 2, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_EnumOptions_msginit = {
&google_protobuf_EnumOptions_submsgs[0],
&google_protobuf_EnumOptions__fields[0],
UPB_SIZE(8, 16), 3, false, 0, 255,
UPB_SIZE(8, 16), 3, _UPB_MSGEXT_EXTENDABLE, 0, 255,
};
static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] = {
&google_protobuf_UninterpretedOption_msginit,
static const upb_msglayout_sub google_protobuf_EnumValueOptions_submsgs[1] = {
{.submsg = &google_protobuf_UninterpretedOption_msginit},
};
static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = {
{1, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR},
{999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY},
{1, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_EnumValueOptions_msginit = {
&google_protobuf_EnumValueOptions_submsgs[0],
&google_protobuf_EnumValueOptions__fields[0],
UPB_SIZE(8, 16), 2, false, 1, 255,
UPB_SIZE(8, 16), 2, _UPB_MSGEXT_EXTENDABLE, 1, 255,
};
static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = {
&google_protobuf_UninterpretedOption_msginit,
static const upb_msglayout_sub google_protobuf_ServiceOptions_submsgs[1] = {
{.submsg = &google_protobuf_UninterpretedOption_msginit},
};
static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = {
{33, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR},
{999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY},
{33, UPB_SIZE(1, 1), 1, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{999, UPB_SIZE(4, 8), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_ServiceOptions_msginit = {
&google_protobuf_ServiceOptions_submsgs[0],
&google_protobuf_ServiceOptions__fields[0],
UPB_SIZE(8, 16), 2, false, 0, 255,
UPB_SIZE(8, 16), 2, _UPB_MSGEXT_EXTENDABLE, 0, 255,
};
static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = {
&google_protobuf_UninterpretedOption_msginit,
static const upb_msglayout_sub google_protobuf_MethodOptions_submsgs[1] = {
{.submsg = &google_protobuf_UninterpretedOption_msginit},
};
static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = {
{33, UPB_SIZE(8, 8), 1, 0, 8, _UPB_MODE_SCALAR},
{34, UPB_SIZE(4, 4), 2, 0, 14, _UPB_MODE_SCALAR},
{999, UPB_SIZE(12, 16), 0, 0, 11, _UPB_MODE_ARRAY},
{33, UPB_SIZE(8, 8), 1, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
{34, UPB_SIZE(4, 4), 2, 0, 14, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
{999, UPB_SIZE(12, 16), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_MethodOptions_msginit = {
&google_protobuf_MethodOptions_submsgs[0],
&google_protobuf_MethodOptions__fields[0],
UPB_SIZE(16, 24), 3, false, 0, 255,
UPB_SIZE(16, 24), 3, _UPB_MSGEXT_EXTENDABLE, 0, 255,
};
static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] = {
&google_protobuf_UninterpretedOption_NamePart_msginit,
static const upb_msglayout_sub google_protobuf_UninterpretedOption_submsgs[1] = {
{.submsg = &google_protobuf_UninterpretedOption_NamePart_msginit},
};
static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = {
{2, UPB_SIZE(56, 80), 0, 0, 11, _UPB_MODE_ARRAY},
{3, UPB_SIZE(32, 32), 1, 0, 12, _UPB_MODE_SCALAR},
{4, UPB_SIZE(8, 8), 2, 0, 4, _UPB_MODE_SCALAR},
{5, UPB_SIZE(16, 16), 3, 0, 3, _UPB_MODE_SCALAR},
{6, UPB_SIZE(24, 24), 4, 0, 1, _UPB_MODE_SCALAR},
{7, UPB_SIZE(40, 48), 5, 0, 12, _UPB_MODE_SCALAR},
{8, UPB_SIZE(48, 64), 6, 0, 12, _UPB_MODE_SCALAR},
{2, UPB_SIZE(56, 80), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
{3, UPB_SIZE(32, 32), 1, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{4, UPB_SIZE(8, 8), 2, 0, 4, _UPB_MODE_SCALAR | (_UPB_REP_8BYTE << 6)},
{5, UPB_SIZE(16, 16), 3, 0, 3, _UPB_MODE_SCALAR | (_UPB_REP_8BYTE << 6)},
{6, UPB_SIZE(24, 24), 4, 0, 1, _UPB_MODE_SCALAR | (_UPB_REP_8BYTE << 6)},
{7, UPB_SIZE(40, 48), 5, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{8, UPB_SIZE(48, 64), 6, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
};
const upb_msglayout google_protobuf_UninterpretedOption_msginit = {
&google_protobuf_UninterpretedOption_submsgs[0],
&google_protobuf_UninterpretedOption__fields[0],
UPB_SIZE(64, 96), 7, false, 0, 255,
UPB_SIZE(64, 96), 7, _UPB_MSGEXT_NONE, 0, 255,
};
static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = {
{1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
{2, UPB_SIZE(1, 1), 2, 0, 8, _UPB_MODE_SCALAR},
{1, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{2, UPB_SIZE(1, 1), 2, 0, 8, _UPB_MODE_SCALAR | (_UPB_REP_1BYTE << 6)},
};
const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = {
NULL,
&google_protobuf_UninterpretedOption_NamePart__fields[0],
UPB_SIZE(16, 32), 2, false, 2, 255,
UPB_SIZE(16, 32), 2, _UPB_MSGEXT_NONE, 2, 255,
};
static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = {
&google_protobuf_SourceCodeInfo_Location_msginit,
static const upb_msglayout_sub google_protobuf_SourceCodeInfo_submsgs[1] = {
{.submsg = &google_protobuf_SourceCodeInfo_Location_msginit},
};
static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = {
{1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
{1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_SourceCodeInfo_msginit = {
&google_protobuf_SourceCodeInfo_submsgs[0],
&google_protobuf_SourceCodeInfo__fields[0],
UPB_SIZE(8, 8), 1, false, 1, 255,
UPB_SIZE(8, 8), 1, _UPB_MSGEXT_NONE, 1, 255,
};
static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = {
{1, UPB_SIZE(20, 40), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED},
{2, UPB_SIZE(24, 48), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED},
{3, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR},
{4, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR},
{6, UPB_SIZE(28, 56), 0, 0, 12, _UPB_MODE_ARRAY},
{1, UPB_SIZE(20, 40), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED | (_UPB_REP_PTR << 6)},
{2, UPB_SIZE(24, 48), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED | (_UPB_REP_PTR << 6)},
{3, UPB_SIZE(4, 8), 1, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{4, UPB_SIZE(12, 24), 2, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{6, UPB_SIZE(28, 56), 0, 0, 12, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = {
NULL,
&google_protobuf_SourceCodeInfo_Location__fields[0],
UPB_SIZE(32, 64), 5, false, 4, 255,
UPB_SIZE(32, 64), 5, _UPB_MSGEXT_NONE, 4, 255,
};
static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] = {
&google_protobuf_GeneratedCodeInfo_Annotation_msginit,
static const upb_msglayout_sub google_protobuf_GeneratedCodeInfo_submsgs[1] = {
{.submsg = &google_protobuf_GeneratedCodeInfo_Annotation_msginit},
};
static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] = {
{1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY},
{1, UPB_SIZE(0, 0), 0, 0, 11, _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6)},
};
const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = {
&google_protobuf_GeneratedCodeInfo_submsgs[0],
&google_protobuf_GeneratedCodeInfo__fields[0],
UPB_SIZE(8, 8), 1, false, 1, 255,
UPB_SIZE(8, 8), 1, _UPB_MSGEXT_NONE, 1, 255,
};
static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = {
{1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED},
{2, UPB_SIZE(12, 16), 1, 0, 12, _UPB_MODE_SCALAR},
{3, UPB_SIZE(4, 4), 2, 0, 5, _UPB_MODE_SCALAR},
{4, UPB_SIZE(8, 8), 3, 0, 5, _UPB_MODE_SCALAR},
{1, UPB_SIZE(20, 32), 0, 0, 5, _UPB_MODE_ARRAY | _UPB_MODE_IS_PACKED | (_UPB_REP_PTR << 6)},
{2, UPB_SIZE(12, 16), 1, 0, 12, _UPB_MODE_SCALAR | (_UPB_REP_STRVIEW << 6)},
{3, UPB_SIZE(4, 4), 2, 0, 5, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
{4, UPB_SIZE(8, 8), 3, 0, 5, _UPB_MODE_SCALAR | (_UPB_REP_4BYTE << 6)},
};
const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = {
NULL,
&google_protobuf_GeneratedCodeInfo_Annotation__fields[0],
UPB_SIZE(24, 48), 4, false, 4, 255,
UPB_SIZE(24, 48), 4, _UPB_MSGEXT_NONE, 4, 255,
};
static const upb_msglayout *messages_layout[27] = {
&google_protobuf_FileDescriptorSet_msginit,
&google_protobuf_FileDescriptorProto_msginit,
&google_protobuf_DescriptorProto_msginit,
&google_protobuf_DescriptorProto_ExtensionRange_msginit,
&google_protobuf_DescriptorProto_ReservedRange_msginit,
&google_protobuf_ExtensionRangeOptions_msginit,
&google_protobuf_FieldDescriptorProto_msginit,
&google_protobuf_OneofDescriptorProto_msginit,
&google_protobuf_EnumDescriptorProto_msginit,
&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit,
&google_protobuf_EnumValueDescriptorProto_msginit,
&google_protobuf_ServiceDescriptorProto_msginit,
&google_protobuf_MethodDescriptorProto_msginit,
&google_protobuf_FileOptions_msginit,
&google_protobuf_MessageOptions_msginit,
&google_protobuf_FieldOptions_msginit,
&google_protobuf_OneofOptions_msginit,
&google_protobuf_EnumOptions_msginit,
&google_protobuf_EnumValueOptions_msginit,
&google_protobuf_ServiceOptions_msginit,
&google_protobuf_MethodOptions_msginit,
&google_protobuf_UninterpretedOption_msginit,
&google_protobuf_UninterpretedOption_NamePart_msginit,
&google_protobuf_SourceCodeInfo_msginit,
&google_protobuf_SourceCodeInfo_Location_msginit,
&google_protobuf_GeneratedCodeInfo_msginit,
&google_protobuf_GeneratedCodeInfo_Annotation_msginit,
};
const upb_msglayout_file google_protobuf_descriptor_proto_upb_file_layout = {
messages_layout,
NULL,
27,
0,
};
#include "upb/port_undef.inc"

@ -2038,6 +2038,8 @@ UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_prot
*UPB_PTR_AT(msg, UPB_SIZE(8, 8), int32_t) = value;
}
extern const upb_msglayout_file google_protobuf_descriptor_proto_upb_file_layout;
#ifdef __cplusplus
} /* extern "C" */
#endif

@ -1 +0,0 @@
Recommended.Proto2.JsonInput.FieldNameExtension.Validator

@ -298,7 +298,8 @@ static void decode_munge(int type, wireval *val) {
}
}
static const upb_msglayout_field *upb_find_field(const upb_msglayout *l,
static const upb_msglayout_field *upb_find_field(upb_decstate *d,
const upb_msglayout *l,
uint32_t field_number,
int *last_field_index) {
static upb_msglayout_field none = {0, 0, 0, 0, 0, 0};
@ -307,23 +308,32 @@ static const upb_msglayout_field *upb_find_field(const upb_msglayout *l,
size_t idx = ((size_t)field_number) - 1; // 0 wraps to SIZE_MAX
if (idx < l->dense_below) {
/* Fastest case: index into dense fields. */
goto found;
}
/* Resume scanning from last_field_index since fields are usually in order. */
int last = *last_field_index;
for (idx = last; idx < l->field_count; idx++) {
if (l->fields[idx].number == field_number) {
goto found;
if (l->dense_below < l->field_count) {
/* Linear search non-dense fields. Resume scanning from last_field_index
* since fields are usually in order. */
int last = *last_field_index;
for (idx = last; idx < l->field_count; idx++) {
if (l->fields[idx].number == field_number) {
goto found;
}
}
}
for (idx = 0; idx < last; idx++) {
if (l->fields[idx].number == field_number) {
goto found;
for (idx = 0; idx < last; idx++) {
if (l->fields[idx].number == field_number) {
goto found;
}
}
}
if (l->ext == _UPB_MSGEXT_EXTENDABLE && d->extreg) {
const upb_msglayout_ext *ext = _upb_extreg_get(d->extreg, l, field_number);
if (ext) return &ext->field;
}
return &none; /* Unknown field. */
found:
@ -332,10 +342,9 @@ static const upb_msglayout_field *upb_find_field(const upb_msglayout *l,
return &l->fields[idx];
}
static upb_msg *decode_newsubmsg(upb_decstate *d,
upb_msglayout const *const *submsgs,
static upb_msg *decode_newsubmsg(upb_decstate *d, const upb_msglayout_sub *subs,
const upb_msglayout_field *field) {
const upb_msglayout *subl = submsgs[field->submsg_index];
const upb_msglayout *subl = subs[field->submsg_index].submsg;
return _upb_msg_new_inl(subl, &d->arena);
}
@ -365,10 +374,10 @@ 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,
upb_msglayout const *const *submsgs,
upb_msg *submsg,
const upb_msglayout_sub *subs,
const upb_msglayout_field *field, int size) {
const upb_msglayout *subl = submsgs[field->submsg_index];
const upb_msglayout *subl = subs[field->submsg_index].submsg;
int saved_delta = decode_pushlimit(d, ptr, size);
if (--d->depth < 0) decode_err(d);
if (!decode_isdone(d, &ptr)) {
@ -398,15 +407,15 @@ static const char *decode_group(upb_decstate *d, const char *ptr,
UPB_FORCEINLINE
static const char *decode_togroup(upb_decstate *d, const char *ptr,
upb_msg *submsg,
upb_msglayout const *const *submsgs,
const upb_msglayout_sub *subs,
const upb_msglayout_field *field) {
const upb_msglayout *subl = submsgs[field->submsg_index];
const upb_msglayout *subl = subs[field->submsg_index].submsg;
return decode_group(d, ptr, submsg, subl, field->number);
}
static const char *decode_toarray(upb_decstate *d, const char *ptr,
upb_msg *msg,
upb_msglayout const *const *submsgs,
const upb_msglayout_sub *subs,
const upb_msglayout_field *field, wireval *val,
int op) {
upb_array **arrp = UPB_PTR_AT(msg, field->offset, void);
@ -442,14 +451,14 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
}
case OP_SUBMSG: {
/* Append submessage / group. */
upb_msg *submsg = decode_newsubmsg(d, submsgs, field);
upb_msg *submsg = decode_newsubmsg(d, subs, field);
*UPB_PTR_AT(_upb_array_ptr(arr), arr->len * sizeof(void *), upb_msg *) =
submsg;
arr->len++;
if (UPB_UNLIKELY(field->descriptortype == UPB_DTYPE_GROUP)) {
return decode_togroup(d, ptr, submsg, submsgs, field);
return decode_togroup(d, ptr, submsg, subs, field);
} else {
return decode_tosubmsg(d, ptr, submsg, submsgs, field, val->size);
return decode_tosubmsg(d, ptr, submsg, subs, field, val->size);
}
}
case OP_FIXPCK_LG2(2):
@ -495,12 +504,13 @@ static const char *decode_toarray(upb_decstate *d, const char *ptr,
}
static const char *decode_tomap(upb_decstate *d, const char *ptr, upb_msg *msg,
upb_msglayout const *const *submsgs,
const upb_msglayout_field *field, wireval *val) {
const upb_msglayout_sub *subs,
const upb_msglayout_field *field,
wireval *val) {
upb_map **map_p = UPB_PTR_AT(msg, field->offset, upb_map *);
upb_map *map = *map_p;
upb_map_entry ent;
const upb_msglayout *entry = submsgs[field->submsg_index];
const upb_msglayout *entry = subs[field->submsg_index].submsg;
if (!map) {
/* Lazily create map. */
@ -520,16 +530,16 @@ static const char *decode_tomap(upb_decstate *d, const char *ptr, upb_msg *msg,
if (entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE ||
entry->fields[1].descriptortype == UPB_DESCRIPTOR_TYPE_GROUP) {
/* Create proactively to handle the case where it doesn't appear. */
ent.v.val = upb_value_ptr(_upb_msg_new(entry->submsgs[0], &d->arena));
ent.v.val = upb_value_ptr(_upb_msg_new(entry->subs[0].submsg, &d->arena));
}
ptr = decode_tosubmsg(d, ptr, &ent.k, submsgs, field, val->size);
ptr = decode_tosubmsg(d, ptr, &ent.k, subs, field, val->size);
_upb_map_set(map, &ent.k, map->key_size, &ent.v, map->val_size, &d->arena);
return ptr;
}
static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg,
upb_msglayout const *const *submsgs,
const upb_msglayout_sub *subs,
const upb_msglayout_field *field, wireval *val,
int op) {
void *mem = UPB_PTR_AT(msg, field->offset, void);
@ -553,13 +563,13 @@ static const char *decode_tomsg(upb_decstate *d, const char *ptr, upb_msg *msg,
upb_msg **submsgp = mem;
upb_msg *submsg = *submsgp;
if (!submsg) {
submsg = decode_newsubmsg(d, submsgs, field);
submsg = decode_newsubmsg(d, subs, field);
*submsgp = submsg;
}
if (UPB_UNLIKELY(type == UPB_DTYPE_GROUP)) {
ptr = decode_togroup(d, ptr, submsg, submsgs, field);
ptr = decode_togroup(d, ptr, submsg, subs, field);
} else {
ptr = decode_tosubmsg(d, ptr, submsg, submsgs, field, val->size);
ptr = decode_tosubmsg(d, ptr, submsg, subs, field, val->size);
}
break;
}
@ -616,7 +626,7 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
field_number = tag >> 3;
wire_type = tag & 7;
field = upb_find_field(layout, field_number, &last_field_index);
field = upb_find_field(d, layout, field_number, &last_field_index);
switch (wire_type) {
case UPB_WIRE_TYPE_VARINT:
@ -664,16 +674,29 @@ static const char *decode_msg(upb_decstate *d, const char *ptr, upb_msg *msg,
}
if (op >= 0) {
/* Known field, possibly an extension. */
upb_msg *field_msg = msg;
const upb_msglayout_sub *subs = layout->subs;
uint8_t mode = field->mode;
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)) decode_err(d);
field_msg = &ext->data;
subs = &ext->ext->sub;
}
/* Parse, using op for dispatch. */
switch (_upb_getmode(field)) {
switch (mode & 3) {
case _UPB_MODE_ARRAY:
ptr = decode_toarray(d, ptr, msg, layout->submsgs, field, &val, op);
ptr = decode_toarray(d, ptr, field_msg, subs, field, &val, op);
break;
case _UPB_MODE_MAP:
ptr = decode_tomap(d, ptr, msg, layout->submsgs, field, &val);
ptr = decode_tomap(d, ptr, field_msg, subs, field, &val);
break;
case _UPB_MODE_SCALAR:
ptr = decode_tomsg(d, ptr, msg, layout->submsgs, field, &val, op);
ptr = decode_tomsg(d, ptr, field_msg, subs, field, &val, op);
break;
default:
UPB_UNREACHABLE();
@ -743,6 +766,7 @@ bool _upb_decode(const char *buf, size_t size, void *msg,
state.alias = options & UPB_DECODE_ALIAS;
}
state.extreg = extreg;
state.limit_ptr = state.end;
state.unknown_msg = NULL;
state.depth = depth ? depth : 64;

@ -48,6 +48,7 @@ typedef struct upb_decstate {
const char *limit_ptr; /* = end + UPB_MIN(limit, 0) */
upb_msg *unknown_msg; /* If non-NULL, add unknown data at buffer flip. */
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;
uint32_t end_group; /* field number of END_GROUP tag, else DECODE_NOGROUP */

@ -74,6 +74,12 @@ struct upb_fielddef {
upb_label_t label_;
};
struct upb_extrange {
const google_protobuf_ExtensionRangeOptions *opts;
int32_t start;
int32_t end;
};
struct upb_msgdef {
const upb_msglayout *layout;
const upb_filedef *file;
@ -83,17 +89,17 @@ struct upb_msgdef {
upb_inttable itof;
upb_strtable ntof;
const upb_extrange *ext_ranges;
const upb_fielddef *fields;
const upb_oneofdef *oneofs;
int field_count;
int oneof_count;
int real_oneof_count;
int ext_range_count;
/* Is this a map-entry message? */
bool map_entry;
upb_wellknowntype_t well_known_type;
/* TODO(haberman): proper extension ranges (there can be multiple). */
};
struct upb_enumdef {
@ -132,6 +138,7 @@ struct upb_filedef {
const upb_msgdef *msgs;
const upb_enumdef *enums;
const upb_fielddef *exts;
const upb_msglayout_ext **ext_layouts;
const upb_symtab *symtab;
int dep_count;
@ -145,6 +152,8 @@ struct upb_symtab {
upb_arena *arena;
upb_strtable syms; /* full_name -> packed def ptr */
upb_strtable files; /* file_name -> upb_filedef* */
upb_inttable exts; /* upb_msglayout_ext* -> upb_fielddef* */
upb_extreg *extreg;
size_t bytes_loaded;
};
@ -518,9 +527,15 @@ const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f) {
}
const upb_msglayout_field *upb_fielddef_layout(const upb_fielddef *f) {
UPB_ASSERT(!upb_fielddef_isextension(f));
return &f->msgdef->layout->fields[f->layout_index];
}
const upb_msglayout_ext *_upb_fielddef_extlayout(const upb_fielddef *f) {
UPB_ASSERT(upb_fielddef_isextension(f));
return f->file->ext_layouts[f->layout_index];
}
bool upb_fielddef_issubmsg(const upb_fielddef *f) {
return upb_fielddef_type(f) == UPB_TYPE_MESSAGE;
}
@ -651,6 +666,10 @@ int upb_msgdef_numrealoneofs(const upb_msgdef *m) {
return m->real_oneof_count;
}
int upb_msgdef_extrangecount(const upb_msgdef *m) {
return m->ext_range_count;
}
int upb_msgdef_fieldcount(const upb_msgdef *m) {
return m->field_count;
}
@ -667,6 +686,11 @@ const upb_msglayout *upb_msgdef_layout(const upb_msgdef *m) {
return m->layout;
}
const upb_extrange *upb_msgdef_extrange(const upb_msgdef *m, int i) {
UPB_ASSERT(i >= 0 && i < m->ext_range_count);
return &m->ext_ranges[i];
}
const upb_fielddef *upb_msgdef_field(const upb_msgdef *m, int i) {
UPB_ASSERT(i >= 0 && i < m->field_count);
return &m->fields[i];
@ -884,12 +908,19 @@ upb_symtab *upb_symtab_new(void) {
s->bytes_loaded = 0;
if (!upb_strtable_init(&s->syms, 32, s->arena) ||
!upb_strtable_init(&s->files, 4, s->arena)) {
upb_arena_free(s->arena);
upb_gfree(s);
s = NULL;
!upb_strtable_init(&s->files, 4, s->arena) ||
!upb_inttable_init(&s->exts, s->arena)) {
goto err;
}
s->extreg = upb_extreg_new(s->arena);
if (!s->extreg) goto err;
return s;
err:
upb_arena_free(s->arena);
upb_gfree(s);
return NULL;
}
const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
@ -898,11 +929,16 @@ const upb_msgdef *upb_symtab_lookupmsg(const upb_symtab *s, const char *sym) {
unpack_def(v, UPB_DEFTYPE_MSG) : NULL;
}
static const void *symtab_lookup2(const upb_symtab *s, const char *sym,
size_t size, upb_deftype_t type) {
upb_value v;
return upb_strtable_lookup2(&s->syms, sym, size, &v) ? unpack_def(v, type)
: NULL;
}
const upb_msgdef *upb_symtab_lookupmsg2(const upb_symtab *s, const char *sym,
size_t len) {
upb_value v;
return upb_strtable_lookup2(&s->syms, sym, len, &v) ?
unpack_def(v, UPB_DEFTYPE_MSG) : NULL;
return symtab_lookup2(s, sym, len, UPB_DEFTYPE_MSG);
}
const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym) {
@ -925,6 +961,11 @@ const upb_fielddef *upb_symtab_lookupext(const upb_symtab *s, const char *sym) {
unpack_def(v, UPB_DEFTYPE_FIELD) : NULL;
}
const upb_fielddef *upb_symtab_lookupext2(const upb_symtab *s, const char *sym,
size_t size) {
return symtab_lookup2(s, sym, size, UPB_DEFTYPE_FIELD);
}
const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name) {
upb_value v;
return upb_strtable_lookup(&s->files, name, &v) ? upb_value_getconstptr(v)
@ -955,7 +996,10 @@ typedef struct {
upb_symtab *symtab;
upb_filedef *file; /* File we are building. */
upb_arena *arena; /* Allocate defs here. */
const upb_msglayout **layouts; /* NULL if we should build layouts. */
const upb_msglayout_file *layout; /* NULL if we should build layouts. */
int enum_count; /* Count of enums built so far. */
int msg_count; /* Count of messages built so far. */
int ext_count; /* Count of extensions built so far. */
upb_status *status; /* Record errors here. */
jmp_buf err; /* longjmp() on error. */
} symtab_addctx;
@ -1095,16 +1139,42 @@ static void fill_fieldlayout(upb_msglayout_field *field, const upb_fielddef *f)
}
if (upb_fielddef_ismap(f)) {
field->mode = _UPB_MODE_MAP;
field->mode = _UPB_MODE_MAP | (_UPB_REP_PTR << 6);
} else if (upb_fielddef_isseq(f)) {
field->mode = _UPB_MODE_ARRAY;
field->mode = _UPB_MODE_ARRAY | (_UPB_REP_PTR << 6);
} else {
field->mode = _UPB_MODE_SCALAR;
/* Maps descriptor type -> elem_size_lg2. */
static const uint8_t sizes[] = {
-1, /* invalid descriptor type */
_UPB_REP_8BYTE, /* DOUBLE */
_UPB_REP_4BYTE, /* FLOAT */
_UPB_REP_8BYTE, /* INT64 */
_UPB_REP_8BYTE, /* UINT64 */
_UPB_REP_4BYTE, /* INT32 */
_UPB_REP_8BYTE, /* FIXED64 */
_UPB_REP_4BYTE, /* FIXED32 */
_UPB_REP_1BYTE, /* BOOL */
_UPB_REP_STRVIEW, /* STRING */
_UPB_REP_PTR, /* GROUP */
_UPB_REP_PTR, /* MESSAGE */
_UPB_REP_STRVIEW, /* BYTES */
_UPB_REP_4BYTE, /* UINT32 */
_UPB_REP_4BYTE, /* ENUM */
_UPB_REP_4BYTE, /* SFIXED32 */
_UPB_REP_8BYTE, /* SFIXED64 */
_UPB_REP_4BYTE, /* SINT32 */
_UPB_REP_8BYTE, /* SINT64 */
};
field->mode = _UPB_MODE_SCALAR | (sizes[field->descriptortype] << 6);
}
if (upb_fielddef_packed(f)) {
field->mode |= _UPB_MODE_IS_PACKED;
}
if (upb_fielddef_isextension(f)) {
field->mode |= _UPB_MODE_IS_EXTENSION;
}
}
/* This function is the dynamic equivalent of message_layout.{cc,h} in upbc.
@ -1115,8 +1185,8 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
upb_msg_oneof_iter oit;
size_t hasbit;
size_t field_count = upb_msgdef_numfields(m);
size_t submsg_count = 0;
const upb_msglayout **submsgs;
size_t sublayout_count = 0;
upb_msglayout_sub *subs;
upb_msglayout_field *fields;
memset(l, 0, sizeof(*l) + sizeof(_upb_fasttable_entry));
@ -1124,18 +1194,24 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
/* Count sub-messages. */
for (size_t i = 0; i < field_count; i++) {
if (upb_fielddef_issubmsg(&m->fields[i])) {
submsg_count++;
sublayout_count++;
}
}
fields = symtab_alloc(ctx, field_count * sizeof(*fields));
submsgs = symtab_alloc(ctx, submsg_count * sizeof(*submsgs));
subs = symtab_alloc(ctx, sublayout_count * sizeof(*subs));
l->field_count = upb_msgdef_numfields(m);
l->fields = fields;
l->submsgs = submsgs;
l->subs = subs;
l->table_mask = 0;
if (upb_msgdef_extrangecount(m) > 0) {
l->ext = _UPB_MSGEXT_EXTENDABLE;
} else {
l->ext = _UPB_MSGEXT_NONE;
}
/* TODO(haberman): initialize fast tables so that reflection-based parsing
* can get the same speeds as linked-in types. */
l->fasttable[0].field_parser = &fastdecode_generic;
@ -1159,7 +1235,7 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
fields[1].submsg_index = 0;
if (upb_fielddef_type(val) == UPB_TYPE_MESSAGE) {
submsgs[0] = upb_fielddef_msgsubdef(val)->layout;
subs[0].submsg = upb_fielddef_msgsubdef(val)->layout;
}
l->field_count = 2;
@ -1178,7 +1254,7 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
*/
/* Allocate hasbits and set basic field attributes. */
submsg_count = 0;
sublayout_count = 0;
for (upb_msg_field_begin(&it, m), hasbit = 0;
!upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
@ -1189,8 +1265,8 @@ static void make_layout(symtab_addctx *ctx, const upb_msgdef *m) {
if (upb_fielddef_issubmsg(f)) {
const upb_msgdef *subm = upb_fielddef_msgsubdef(f);
field->submsg_index = submsg_count++;
submsgs[field->submsg_index] = subm->layout;
field->submsg_index = sublayout_count++;
subs[field->submsg_index].submsg = subm->layout;
}
if (upb_fielddef_haspresence(f) && !upb_fielddef_realcontainingoneof(f)) {
@ -1656,12 +1732,11 @@ static void create_fielddef(
upb_strtable_insert(&m->ntof, json_name, json_size, json_v, ctx->arena);
}
if (ctx->layouts) {
if (ctx->layout) {
const upb_msglayout_field *fields = m->layout->fields;
int count = m->layout->field_count;
bool found = false;
int i;
for (i = 0; i < count; i++) {
for (int i = 0; i < count; i++) {
if (fields[i].number == field_number) {
f->layout_index = i;
found = true;
@ -1672,9 +1747,15 @@ static void create_fielddef(
}
} else {
/* extension field. */
f = (upb_fielddef*)&ctx->file->exts[ctx->file->ext_count++];
uint16_t layout_index = ctx->ext_count++;
f = (upb_fielddef*)&ctx->file->exts[layout_index];
f->layout_index = layout_index;
f->is_extension_ = true;
symtab_add(ctx, full_name, pack_def(f, UPB_DEFTYPE_FIELD));
if (ctx->layout) {
UPB_ASSERT(ctx->file->ext_layouts[f->layout_index]->field.number ==
field_number);
}
}
f->full_name = full_name;
@ -1763,7 +1844,7 @@ static void create_enumdef(
name = google_protobuf_EnumDescriptorProto_name(enum_proto);
check_ident(ctx, name, false);
e = (upb_enumdef*)&ctx->file->enums[ctx->file->enum_count++];
e = (upb_enumdef*)&ctx->file->enums[ctx->enum_count++];
e->full_name = makefullname(ctx, prefix, name);
symtab_add(ctx, e->full_name, pack_def(e, UPB_DEFTYPE_ENUM));
@ -1816,18 +1897,23 @@ static void create_msgdef(symtab_addctx *ctx, const char *prefix,
const google_protobuf_FieldDescriptorProto *const *fields;
const google_protobuf_EnumDescriptorProto *const *enums;
const google_protobuf_DescriptorProto *const *msgs;
size_t i, n_oneof, n_field, n;
const google_protobuf_DescriptorProto_ExtensionRange *const *ext_ranges;
size_t i, n_oneof, n_field, n_ext_range, n;
upb_strview name;
name = google_protobuf_DescriptorProto_name(msg_proto);
check_ident(ctx, name, false);
m = (upb_msgdef*)&ctx->file->msgs[ctx->file->msg_count++];
int msg_index = ctx->msg_count;
m = (upb_msgdef*)&ctx->file->msgs[msg_index];
m->full_name = makefullname(ctx, prefix, name);
ctx->msg_count++;
symtab_add(ctx, m->full_name, pack_def(m, UPB_DEFTYPE_MSG));
oneofs = google_protobuf_DescriptorProto_oneof_decl(msg_proto, &n_oneof);
fields = google_protobuf_DescriptorProto_field(msg_proto, &n_field);
ext_ranges =
google_protobuf_DescriptorProto_extension_range(msg_proto, &n_ext_range);
CHK_OOM(upb_inttable_init(&m->itof, ctx->arena));
CHK_OOM(upb_strtable_init(&m->ntof, n_oneof + n_field, ctx->arena));
@ -1841,9 +1927,10 @@ static void create_msgdef(symtab_addctx *ctx, const char *prefix,
m->map_entry = google_protobuf_MessageOptions_map_entry(options);
}
if (ctx->layouts) {
m->layout = *ctx->layouts;
ctx->layouts++;
if (ctx->layout) {
/* create_fielddef() below depends on this being set. */
m->layout = ctx->layout->msgs[msg_index];
UPB_ASSERT(n_field == m->layout->field_count);
} else {
/* Allocate now (to allow cross-linking), populate later. */
m->layout = symtab_alloc(
@ -1862,6 +1949,15 @@ static void create_msgdef(symtab_addctx *ctx, const char *prefix,
create_fielddef(ctx, m->full_name, m, fields[i]);
}
m->ext_range_count = n_ext_range;
m->ext_ranges = symtab_alloc(ctx, sizeof(*m->ext_ranges) * n_ext_range);
for (i = 0; i < n_ext_range; i++) {
const google_protobuf_DescriptorProto_ExtensionRange *r = ext_ranges[i];
upb_extrange *r_def = (upb_extrange*)&m->ext_ranges[i];
r_def->start = google_protobuf_DescriptorProto_ExtensionRange_start(r);
r_def->end = google_protobuf_DescriptorProto_ExtensionRange_end(r);
}
finalize_oneofs(ctx, m);
assign_msg_wellknowntype(m);
upb_inttable_compact(&m->itof, ctx->arena);
@ -1873,6 +1969,11 @@ static void create_msgdef(symtab_addctx *ctx, const char *prefix,
create_enumdef(ctx, m->full_name, enums[i]);
}
fields = google_protobuf_DescriptorProto_extension(msg_proto, &n);
for (i = 0; i < n; i++) {
create_fielddef(ctx, m->full_name, NULL, fields[i]);
}
msgs = google_protobuf_DescriptorProto_nested_type(msg_proto, &n);
for (i = 0; i < n; i++) {
create_msgdef(ctx, m->full_name, msgs[i]);
@ -1929,6 +2030,22 @@ static void resolve_fielddef(symtab_addctx *ctx, const char *prefix,
name = google_protobuf_FieldDescriptorProto_extendee(field_proto);
f->msgdef = symtab_resolve(ctx, f, prefix, name, UPB_DEFTYPE_MSG);
const upb_msglayout_ext *ext = ctx->file->ext_layouts[f->layout_index];
if (ctx->layout) {
UPB_ASSERT(upb_fielddef_number(f) == ext->field.number);
} else {
upb_msglayout_ext *mut_ext = (upb_msglayout_ext*)ext;
fill_fieldlayout(&mut_ext->field, f);
mut_ext->field.presence = 0;
mut_ext->field.offset = 0;
mut_ext->field.submsg_index = 0;
mut_ext->extendee = f->msgdef->layout;
mut_ext->sub.submsg = f->sub.msgdef->layout;
}
CHK_OOM(upb_inttable_insert(&ctx->symtab->exts, (uintptr_t)ext,
upb_value_constptr(f), ctx->arena));
}
if ((upb_fielddef_issubmsg(f) || f->type_ == UPB_DESCRIPTOR_TYPE_ENUM) &&
@ -1987,10 +2104,26 @@ static void build_filedef(
file->enums = symtab_alloc(ctx, sizeof(*file->enums) * file->enum_count);
file->exts = symtab_alloc(ctx, sizeof(*file->exts) * file->ext_count);
/* In the second pass we increment these as defs are added. */
file->msg_count = 0;
file->enum_count = 0;
file->ext_count = 0;
ctx->msg_count = 0;
ctx->enum_count = 0;
ctx->ext_count = 0;
if (ctx->layout) {
/* We are using the ext layouts that were passed in. */
file->ext_layouts = ctx->layout->exts;
if (ctx->layout->ext_count != file->ext_count) {
symtab_errf(ctx, "Extension count did not match layout (%d vs %d)",
ctx->layout->ext_count, file->ext_count);
}
} else {
/* We are building ext layouts from scratch. */
file->ext_layouts =
symtab_alloc(ctx, sizeof(*file->ext_layouts) * file->ext_count);
upb_msglayout_ext *ext = symtab_alloc(ctx, sizeof(*ext) * file->ext_count);
for (int i = 0; i < file->ext_count; i++) {
file->ext_layouts[i] = &ext[i];
}
}
if (!google_protobuf_FileDescriptorProto_has_name(file_proto)) {
symtab_errf(ctx, "File has no name");
@ -2071,11 +2204,12 @@ static void build_filedef(
/* Create extensions. */
exts = google_protobuf_FileDescriptorProto_extension(file_proto, &n);
file->exts = symtab_alloc(ctx, sizeof(*file->exts) * n);
for (i = 0; i < n; i++) {
create_fielddef(ctx, file->package, NULL, exts[i]);
}
UPB_ASSERT(ctx->ext_count == file->ext_count);
/* Now that all names are in the table, build layouts and resolve refs. */
for (i = 0; i < (size_t)file->ext_count; i++) {
resolve_fielddef(ctx, file->package, (upb_fielddef*)&file->exts[i]);
@ -2089,25 +2223,28 @@ static void build_filedef(
}
}
if (!ctx->layouts) {
if (!ctx->layout) {
for (i = 0; i < (size_t)file->msg_count; i++) {
const upb_msgdef *m = &file->msgs[i];
make_layout(ctx, m);
}
}
CHK_OOM(
_upb_extreg_add(ctx->symtab->extreg, file->ext_layouts, file->ext_count));
}
static void remove_filedef(upb_symtab *s, upb_filedef *file) {
static void remove_filedef(symtab_addctx *ctx, upb_symtab *s, upb_filedef *file) {
int i;
for (i = 0; i < file->msg_count; i++) {
for (i = 0; i < ctx->msg_count; i++) {
const char *name = file->msgs[i].full_name;
upb_strtable_remove(&s->syms, name, strlen(name), NULL);
}
for (i = 0; i < file->enum_count; i++) {
for (i = 0; i < ctx->enum_count; i++) {
const char *name = file->enums[i].full_name;
upb_strtable_remove(&s->syms, name, strlen(name), NULL);
}
for (i = 0; i < file->ext_count; i++) {
for (i = 0; i < ctx->ext_count; i++) {
const char *name = file->exts[i].full_name;
upb_strtable_remove(&s->syms, name, strlen(name), NULL);
}
@ -2115,7 +2252,7 @@ static void remove_filedef(upb_symtab *s, upb_filedef *file) {
static const upb_filedef *_upb_symtab_addfile(
upb_symtab *s, const google_protobuf_FileDescriptorProto *file_proto,
const upb_msglayout **layouts, upb_status *status) {
const upb_msglayout_file *layout, upb_status *status) {
symtab_addctx ctx;
upb_strview name = google_protobuf_FileDescriptorProto_name(file_proto);
@ -2126,7 +2263,7 @@ static const upb_filedef *_upb_symtab_addfile(
}
ctx.symtab = s;
ctx.layouts = layouts;
ctx.layout = layout;
ctx.status = status;
ctx.file = NULL;
ctx.arena = upb_arena_new();
@ -2139,7 +2276,7 @@ static const upb_filedef *_upb_symtab_addfile(
if (UPB_UNLIKELY(UPB_SETJMP(ctx.err))) {
UPB_ASSERT(!upb_ok(status));
if (ctx.file) {
remove_filedef(s, ctx.file);
remove_filedef(&ctx, s, ctx.file);
ctx.file = NULL;
}
} else {
@ -2198,14 +2335,16 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) {
goto err;
}
if (!_upb_symtab_addfile(s, file, init->layouts, &status)) goto err;
if (!_upb_symtab_addfile(s, file, init->layout, &status)) goto err;
upb_arena_free(arena);
return true;
err:
fprintf(stderr, "Error loading compiled-in descriptor: %s\n",
upb_status_errmsg(&status));
fprintf(stderr,
"Error loading compiled-in descriptor for file '%s' (this should "
"never happen): %s\n",
init->filename, upb_status_errmsg(&status));
upb_arena_free(arena);
return false;
}
@ -2218,4 +2357,16 @@ upb_arena *_upb_symtab_arena(const upb_symtab *s) {
return s->arena;
}
const upb_fielddef *_upb_symtab_lookupextfield(const upb_symtab *s,
const upb_msglayout_ext *ext) {
upb_value v;
bool ok = upb_inttable_lookup(&s->exts, (uintptr_t)ext, &v);
UPB_ASSERT(ok);
return upb_value_getconstptr(v);
}
const upb_extreg *upb_symtab_extreg(const upb_symtab *s) {
return s->extreg;
}
#undef CHK_OOM

@ -56,6 +56,8 @@ struct upb_enumdef;
typedef struct upb_enumdef upb_enumdef;
struct upb_enumvaldef;
typedef struct upb_enumvaldef upb_enumvaldef;
struct upb_extrange;
typedef struct upb_extrange upb_extrange;
struct upb_fielddef;
typedef struct upb_fielddef upb_fielddef;
struct upb_filedef;
@ -137,6 +139,7 @@ bool upb_fielddef_haspresence(const upb_fielddef *f);
const upb_msgdef *upb_fielddef_msgsubdef(const upb_fielddef *f);
const upb_enumdef *upb_fielddef_enumsubdef(const upb_fielddef *f);
const upb_msglayout_field *upb_fielddef_layout(const upb_fielddef *f);
const upb_msglayout_ext *_upb_fielddef_extlayout(const upb_fielddef *f);
/* upb_oneofdef ***************************************************************/
@ -201,8 +204,10 @@ bool upb_msgdef_mapentry(const upb_msgdef *m);
upb_wellknowntype_t upb_msgdef_wellknowntype(const upb_msgdef *m);
bool upb_msgdef_iswrapper(const upb_msgdef *m);
bool upb_msgdef_isnumberwrapper(const upb_msgdef *m);
int upb_msgdef_extrangecount(const upb_msgdef *m);
int upb_msgdef_fieldcount(const upb_msgdef *m);
int upb_msgdef_oneofcount(const upb_msgdef *m);
const upb_extrange *upb_msgdef_extrange(const upb_msgdef *m, int i);
const upb_fielddef *upb_msgdef_field(const upb_msgdef *m, int i);
const upb_oneofdef *upb_msgdef_oneof(const upb_msgdef *m, int i);
const upb_fielddef *upb_msgdef_itof(const upb_msgdef *m, uint32_t i);
@ -258,6 +263,14 @@ bool upb_msg_oneof_iter_isequal(const upb_msg_oneof_iter *iter1,
const upb_msg_oneof_iter *iter2);
/* END DEPRECATED */
/* upb_extrange ***************************************************************/
const google_protobuf_ExtensionRangeOptions *upb_extrange_options(
const upb_extrange *r);
bool upb_extrange_hasoptions(const upb_extrange *r);
int32_t upb_extrange_start(const upb_extrange *r);
int32_t upb_extrange_end(const upb_extrange *r);
/* upb_enumdef ****************************************************************/
typedef upb_strtable_iter upb_enum_iter;
@ -321,6 +334,8 @@ const upb_enumdef *upb_symtab_lookupenum(const upb_symtab *s, const char *sym);
const upb_enumvaldef *upb_symtab_lookupenumval(const upb_symtab *s,
const char *sym);
const upb_fielddef *upb_symtab_lookupext(const upb_symtab *s, const char *sym);
const upb_fielddef *upb_symtab_lookupext2(const upb_symtab *s, const char *sym,
size_t len);
const upb_filedef *upb_symtab_lookupfile(const upb_symtab *s, const char *name);
const upb_filedef *upb_symtab_lookupfile2(
const upb_symtab *s, const char *name, size_t len);
@ -330,11 +345,14 @@ const upb_filedef *upb_symtab_addfile(
upb_status *status);
size_t _upb_symtab_bytesloaded(const upb_symtab *s);
upb_arena *_upb_symtab_arena(const upb_symtab *s);
const upb_fielddef *_upb_symtab_lookupextfield(const upb_symtab *s,
const upb_msglayout_ext *ext);
const upb_extreg *upb_symtab_extreg(const upb_symtab *s);
/* For generated code only: loads a generated descriptor. */
typedef struct upb_def_init {
struct upb_def_init **deps; /* Dependencies of this file. */
const upb_msglayout **layouts; /* Pre-order layouts of all messages. */
const upb_msglayout_file *layout;
const char *filename;
upb_strview descriptor; /* Serialized descriptor. */
} upb_def_init;

@ -187,17 +187,14 @@ static void encode_message(upb_encstate *e, const upb_msg *msg,
const upb_msglayout *m, size_t *size);
static void encode_scalar(upb_encstate *e, const void *_field_mem,
const upb_msglayout *m, const upb_msglayout_field *f,
bool skip_zero_value) {
const upb_msglayout_sub *subs,
const upb_msglayout_field *f) {
const char *field_mem = _field_mem;
int wire_type;
#define CASE(ctype, type, wtype, encodeval) \
{ \
ctype val = *(ctype *)field_mem; \
if (skip_zero_value && val == 0) { \
return; \
} \
encode_##type(e, encodeval); \
wire_type = wtype; \
break; \
@ -231,9 +228,6 @@ static void encode_scalar(upb_encstate *e, const void *_field_mem,
case UPB_DESCRIPTOR_TYPE_STRING:
case UPB_DESCRIPTOR_TYPE_BYTES: {
upb_strview view = *(upb_strview*)field_mem;
if (skip_zero_value && view.size == 0) {
return;
}
encode_bytes(e, view.data, view.size);
encode_varint(e, view.size);
wire_type = UPB_WIRE_TYPE_DELIMITED;
@ -242,7 +236,7 @@ static void encode_scalar(upb_encstate *e, const void *_field_mem,
case UPB_DESCRIPTOR_TYPE_GROUP: {
size_t size;
void *submsg = *(void **)field_mem;
const upb_msglayout *subm = m->submsgs[f->submsg_index];
const upb_msglayout *subm = subs[f->submsg_index].submsg;
if (submsg == NULL) {
return;
}
@ -256,7 +250,7 @@ static void encode_scalar(upb_encstate *e, const void *_field_mem,
case UPB_DESCRIPTOR_TYPE_MESSAGE: {
size_t size;
void *submsg = *(void **)field_mem;
const upb_msglayout *subm = m->submsgs[f->submsg_index];
const upb_msglayout *subm = subs[f->submsg_index].submsg;
if (submsg == NULL) {
return;
}
@ -276,7 +270,8 @@ static void encode_scalar(upb_encstate *e, const void *_field_mem,
}
static void encode_array(upb_encstate *e, const upb_msg *msg,
const upb_msglayout *m, const upb_msglayout_field *f) {
const upb_msglayout_sub *subs,
const upb_msglayout_field *f) {
const upb_array *arr = *UPB_PTR_AT(msg, f->offset, upb_array*);
bool packed = f->mode & _UPB_MODE_IS_PACKED;
size_t pre_len = e->limit - e->ptr;
@ -344,7 +339,7 @@ static void encode_array(upb_encstate *e, const upb_msg *msg,
case UPB_DESCRIPTOR_TYPE_GROUP: {
const void *const*start = _upb_array_constptr(arr);
const void *const*ptr = start + arr->len;
const upb_msglayout *subm = m->submsgs[f->submsg_index];
const upb_msglayout *subm = subs[f->submsg_index].submsg;
if (--e->depth == 0) encode_err(e);
do {
size_t size;
@ -359,7 +354,7 @@ static void encode_array(upb_encstate *e, const upb_msg *msg,
case UPB_DESCRIPTOR_TYPE_MESSAGE: {
const void *const*start = _upb_array_constptr(arr);
const void *const*ptr = start + arr->len;
const upb_msglayout *subm = m->submsgs[f->submsg_index];
const upb_msglayout *subm = subs[f->submsg_index].submsg;
if (--e->depth == 0) encode_err(e);
do {
size_t size;
@ -387,17 +382,18 @@ static void encode_mapentry(upb_encstate *e, uint32_t number,
const upb_msglayout_field *val_field = &layout->fields[1];
size_t pre_len = e->limit - e->ptr;
size_t size;
encode_scalar(e, &ent->v, layout, val_field, false);
encode_scalar(e, &ent->k, layout, key_field, false);
encode_scalar(e, &ent->v, layout->subs, val_field);
encode_scalar(e, &ent->k, layout->subs, key_field);
size = (e->limit - e->ptr) - pre_len;
encode_varint(e, size);
encode_tag(e, number, UPB_WIRE_TYPE_DELIMITED);
}
static void encode_map(upb_encstate *e, const upb_msg *msg,
const upb_msglayout *m, const upb_msglayout_field *f) {
const upb_msglayout_sub *subs,
const upb_msglayout_field *f) {
const upb_map *map = *UPB_PTR_AT(msg, f->offset, const upb_map*);
const upb_msglayout *layout = m->submsgs[f->submsg_index];
const upb_msglayout *layout = subs[f->submsg_index].submsg;
UPB_ASSERT(layout->field_count == 2);
if (map == NULL) return;
@ -425,28 +421,65 @@ static void encode_map(upb_encstate *e, const upb_msg *msg,
}
}
static void encode_scalarfield(upb_encstate *e, const char *msg,
const upb_msglayout *m,
const upb_msglayout_field *f) {
bool skip_empty = false;
static bool encode_shouldencode(upb_encstate *e, const upb_msg *msg,
const upb_msglayout_sub *subs,
const upb_msglayout_field *f) {
if (f->presence == 0) {
/* Proto3 presence. */
skip_empty = true;
/* Proto3 presence or map/array. */
const void *mem = UPB_PTR_AT(msg, f->offset, void);
switch (f->mode >> 6) {
case _UPB_REP_1BYTE: {
char ch;
memcpy(&ch, mem, 1);
return ch != 0;
}
case _UPB_REP_4BYTE: {
uint32_t u32;
memcpy(&u32, mem, 4);
return u32 != 0;
}
case _UPB_REP_8BYTE: {
uint64_t u64;
memcpy(&u64, mem, 8);
return u64 != 0;
}
case _UPB_REP_STRVIEW: {
const upb_strview *str = (const upb_strview*)mem;
return str->size != 0;
}
default:
UPB_UNREACHABLE();
}
} else if (f->presence > 0) {
/* Proto2 presence: hasbit. */
if (!_upb_hasbit_field(msg, f)) return;
return _upb_hasbit_field(msg, f);
} else {
/* Field is in a oneof. */
if (_upb_getoneofcase_field(msg, f) != f->number) return;
return _upb_getoneofcase_field(msg, f) == f->number;
}
}
static void encode_field(upb_encstate *e, const upb_msg *msg,
const upb_msglayout_sub *subs,
const upb_msglayout_field *field) {
switch (_upb_getmode(field)) {
case _UPB_MODE_ARRAY:
encode_array(e, msg, subs, field);
break;
case _UPB_MODE_MAP:
encode_map(e, msg, subs, field);
break;
case _UPB_MODE_SCALAR:
encode_scalar(e, UPB_PTR_AT(msg, field->offset, void), subs, field);
break;
default:
UPB_UNREACHABLE();
}
encode_scalar(e, msg + f->offset, m, f, skip_empty);
}
static void encode_message(upb_encstate *e, const upb_msg *msg,
const upb_msglayout *m, size_t *size) {
size_t pre_len = e->limit - e->ptr;
const upb_msglayout_field *f = &m->fields[m->field_count];
const upb_msglayout_field *first = &m->fields[0];
if ((e->options & UPB_ENCODE_SKIPUNKNOWN) == 0) {
size_t unknown_size;
@ -457,20 +490,26 @@ static void encode_message(upb_encstate *e, const upb_msg *msg,
}
}
if (m->ext != _UPB_MSGEXT_NONE) {
/* Encode all extensions together. Unlike C++, we do not attempt to keep
* these in field number order relative to normal fields or even to each
* other. */
size_t ext_count;
const upb_msg_ext *ext = _upb_msg_getexts(msg, &ext_count);
const upb_msg_ext *end = ext + ext_count;
if (ext_count) {
for (; ext != end; ext++) {
encode_field(e, &ext->data, &ext->ext->sub, &ext->ext->field);
}
}
}
const upb_msglayout_field *f = &m->fields[m->field_count];
const upb_msglayout_field *first = &m->fields[0];
while (f != first) {
f--;
switch (_upb_getmode(f)) {
case _UPB_MODE_ARRAY:
encode_array(e, msg, m, f);
break;
case _UPB_MODE_MAP:
encode_map(e, msg, m, f);
break;
case _UPB_MODE_SCALAR:
encode_scalarfield(e, msg, m, f);
break;
default:
UPB_UNREACHABLE();
if (encode_shouldencode(e, msg, m->subs, f)) {
encode_field(e, msg, m->subs, f);
}
}

@ -45,7 +45,7 @@
typedef struct {
const char *ptr, *end;
upb_arena *arena; /* TODO: should we have a tmp arena for tmp data? */
const upb_symtab *any_pool;
const upb_symtab *symtab;
int depth;
upb_status *status;
jmp_buf err;
@ -931,7 +931,20 @@ static void jsondec_field(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
name = jsondec_string(d);
jsondec_entrysep(d);
f = upb_msgdef_lookupjsonname(m, name.data, name.size);
if (name.size >= 2 && name.data[0] == '[' &&
name.data[name.size - 1] == ']') {
f = upb_symtab_lookupext2(d->symtab, name.data + 1, name.size - 2);
if (f && upb_fielddef_containingtype(f) != m) {
jsondec_errf(
d, "Extension %s extends message %s, but was seen in message %s",
upb_fielddef_fullname(f),
upb_msgdef_fullname(upb_fielddef_containingtype(f)),
upb_msgdef_fullname(m));
}
} else {
f = upb_msgdef_lookupjsonname(m, name.data, name.size);
}
if (!f) {
if ((d->options & UPB_JSONDEC_IGNOREUNKNOWN) == 0) {
@ -1335,7 +1348,7 @@ static const upb_msgdef *jsondec_typeurl(jsondec *d, upb_msg *msg,
}
ptr++;
type_m = upb_symtab_lookupmsg2(d->any_pool, ptr, end - ptr);
type_m = upb_symtab_lookupmsg2(d->symtab, ptr, end - ptr);
if (!type_m) {
jsondec_err(d, "Type was not found");
@ -1453,7 +1466,7 @@ static void jsondec_wellknown(jsondec *d, upb_msg *msg, const upb_msgdef *m) {
}
bool upb_json_decode(const char *buf, size_t size, upb_msg *msg,
const upb_msgdef *m, const upb_symtab *any_pool,
const upb_msgdef *m, const upb_symtab *symtab,
int options, upb_arena *arena, upb_status *status) {
jsondec d;
@ -1462,7 +1475,7 @@ bool upb_json_decode(const char *buf, size_t size, upb_msg *msg,
d.ptr = buf;
d.end = buf + size;
d.arena = arena;
d.any_pool = any_pool;
d.symtab = symtab;
d.status = status;
d.options = options;
d.depth = 64;

@ -39,7 +39,7 @@ enum {
};
bool upb_json_decode(const char *buf, size_t size, upb_msg *msg,
const upb_msgdef *m, const upb_symtab *any_pool,
const upb_msgdef *m, const upb_symtab *symtab,
int options, upb_arena *arena, upb_status *status);
#ifdef __cplusplus

@ -670,15 +670,19 @@ static void jsonenc_fieldval(jsonenc *e, const upb_fielddef *f,
upb_msgval val, bool *first) {
const char *name;
if (e->options & UPB_JSONENC_PROTONAMES) {
name = upb_fielddef_name(f);
jsonenc_putsep(e, ",", first);
if (upb_fielddef_isextension(f)) {
jsonenc_printf(e, "\"[%s]\":", upb_fielddef_fullname(f));
} else {
name = upb_fielddef_jsonname(f);
if (e->options & UPB_JSONENC_PROTONAMES) {
name = upb_fielddef_name(f);
} else {
name = upb_fielddef_jsonname(f);
}
jsonenc_printf(e, "\"%s\":", name);
}
jsonenc_putsep(e, ",", first);
jsonenc_printf(e, "\"%s\":", name);
if (upb_fielddef_ismap(f)) {
jsonenc_map(e, val.map_val, f);
} else if (upb_fielddef_isseq(f)) {

@ -137,6 +137,18 @@ const upb_msg_ext *_upb_msg_getext(const upb_msg *msg,
return NULL;
}
void _upb_msg_clearext(upb_msg *msg, const upb_msglayout_ext *ext_l) {
upb_msg_internal *in = upb_msg_getinternal(msg);
if (!in->internal) return;
const upb_msg_ext *base =
UPB_PTR_AT(in->internal, in->internal->ext_begin, void);
upb_msg_ext *ext = (void*)_upb_msg_getext(msg, ext_l);
if (ext) {
*ext = *base;
in->internal->ext_begin += sizeof(upb_msg_ext);
}
}
upb_msg_ext *_upb_msg_getorcreateext(upb_msg *msg, const upb_msglayout_ext *e,
upb_arena *arena) {
upb_msg_ext *ext = (upb_msg_ext*)_upb_msg_getext(msg, e);
@ -361,14 +373,15 @@ upb_extreg *upb_extreg_new(upb_arena *arena) {
return r;
}
bool _upb_extreg_add(upb_extreg *r, const upb_msglayout_ext *e, size_t count) {
bool _upb_extreg_add(upb_extreg *r, const upb_msglayout_ext **e, size_t count) {
char buf[EXTREG_KEY_SIZE];
const upb_msglayout_ext *start = e;
const upb_msglayout_ext *end = e + count;
const upb_msglayout_ext **start = e;
const upb_msglayout_ext **end = e + count;
for (; e < end; e++) {
extreg_key(buf, e->extendee, e->field.number);
const upb_msglayout_ext *ext = *e;
extreg_key(buf, ext->extendee, ext->field.number);
if (!upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE,
upb_value_constptr(e), r->arena)) {
upb_value_constptr(ext), r->arena)) {
goto failure;
}
}
@ -377,15 +390,15 @@ bool _upb_extreg_add(upb_extreg *r, const upb_msglayout_ext *e, size_t count) {
failure:
/* Back out the entries previously added. */
for (end = e, e = start; e < end; e++) {
extreg_key(buf, e->extendee, e->field.number);
const upb_msglayout_ext *ext = *e;
extreg_key(buf, ext->extendee, ext->field.number);
upb_strtable_remove(&r->exts, buf, EXTREG_KEY_SIZE, NULL);
}
return false;
}
const upb_msglayout_field *_upb_extreg_get(const upb_extreg *r,
const upb_msglayout *l,
uint32_t num) {
const upb_msglayout_ext *_upb_extreg_get(const upb_extreg *r,
const upb_msglayout *l, uint32_t num) {
char buf[EXTREG_KEY_SIZE];
upb_value v;
extreg_key(buf, l, num);

@ -1,3 +1,30 @@
/*
* Copyright (c) 2009-2021, Google LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Google LLC nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
** Our memory representation for parsing tables and messages themselves.
** Functions in this file are used by generated code and possibly reflection.
@ -42,7 +69,7 @@ typedef struct {
int16_t presence; /* If >0, hasbit_index. If <0, ~oneof_index. */
uint16_t submsg_index; /* undefined if descriptortype != MESSAGE or GROUP. */
uint8_t descriptortype;
int8_t mode; /* upb_fieldmode, with flags from upb_labelflags */
uint8_t mode; /* upb_fieldmode | upb_labelflags | (upb_rep << 6) */
} upb_msglayout_field;
typedef enum {
@ -54,6 +81,22 @@ typedef enum {
/* Extra flags on the mode field. */
enum upb_labelflags {
_UPB_MODE_IS_PACKED = 4,
_UPB_MODE_IS_EXTENSION = 8,
};
/* Representation in the message. Derivable from descriptortype and mode, but
* fast access helps the serializer. */
enum upb_rep {
_UPB_REP_1BYTE = 0,
_UPB_REP_4BYTE = 1,
_UPB_REP_8BYTE = 2,
_UPB_REP_STRVIEW = 3,
#if UINTPTR_MAX == 0xffffffff
_UPB_REP_PTR = _UPB_REP_4BYTE,
#else
_UPB_REP_PTR = _UPB_REP_8BYTE,
#endif
};
UPB_INLINE upb_fieldmode _upb_getmode(const upb_msglayout_field *field) {
@ -82,14 +125,25 @@ typedef struct {
_upb_field_parser *field_parser;
} _upb_fasttable_entry;
typedef union {
const struct upb_msglayout *submsg;
// TODO: const upb_enumlayout *subenum;
} upb_msglayout_sub;
typedef enum {
_UPB_MSGEXT_NONE = 0, // Non-extendable message.
_UPB_MSGEXT_EXTENDABLE = 1, // Normal extendable message.
// TODO: MessageSet
} upb_msgext_mode;
struct upb_msglayout {
const struct upb_msglayout *const* submsgs;
const upb_msglayout_sub *subs;
const upb_msglayout_field *fields;
/* Must be aligned to sizeof(void*). Doesn't include internal members like
* unknown fields, extension dict, pointer to msglayout, etc. */
uint16_t size;
uint16_t field_count;
bool extendable;
uint8_t ext; // upb_msgext_mode, declared as uint8_t so sizeof(ext) == 1
uint8_t dense_below;
uint8_t table_mask;
/* To constant-initialize the tables of variable length, we need a flexible
@ -100,22 +154,28 @@ struct upb_msglayout {
typedef struct {
upb_msglayout_field field;
const upb_msglayout *extendee;
const upb_msglayout *submsg; /* NULL for non-submessage fields. */
upb_msglayout_sub sub; /* NULL unless submessage or proto2 enum */
} upb_msglayout_ext;
typedef struct {
const upb_msglayout **msgs;
const upb_msglayout_ext **exts;
int msg_count;
int ext_count;
} upb_msglayout_file;
/** upb_extreg ****************************************************************/
/* Adds the given extension info for message type |l| and field number |num|
* into the registry. Returns false if this message type and field number were
* already in the map, or if memory allocation fails. */
bool _upb_extreg_add(upb_extreg *r, const upb_msglayout_ext *e, size_t count);
bool _upb_extreg_add(upb_extreg *r, const upb_msglayout_ext **e, size_t count);
/* Looks up the extension (if any) defined for message type |l| and field
* number |num|. If an extension was found, copies the field info into |*ext|
* and returns true. Otherwise returns false. */
const upb_msglayout_field *_upb_extreg_get(const upb_extreg *r,
const upb_msglayout *l,
uint32_t num);
const upb_msglayout_ext *_upb_extreg_get(const upb_extreg *r,
const upb_msglayout *l, uint32_t num);
/** upb_msg *******************************************************************/
@ -216,6 +276,8 @@ const upb_msg_ext *_upb_msg_getexts(const upb_msg *msg, size_t *count);
const upb_msg_ext *_upb_msg_getext(const 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) {

@ -108,15 +108,20 @@ static upb_msgval _upb_msg_getraw(const upb_msg *msg, const upb_fielddef *f) {
}
bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f) {
const upb_msglayout_field *field = upb_fielddef_layout(f);
if (in_oneof(field)) {
return _upb_getoneofcase_field(msg, field) == field->number;
} else if (field->presence > 0) {
return _upb_hasbit_field(msg, field);
if (upb_fielddef_isextension(f)) {
const upb_msglayout_ext *ext = _upb_fielddef_extlayout(f);
return _upb_msg_getext(msg, ext) != NULL;
} else {
UPB_ASSERT(field->descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE ||
field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP);
return _upb_msg_getraw(msg, f).msg_val != NULL;
const upb_msglayout_field *field = upb_fielddef_layout(f);
if (in_oneof(field)) {
return _upb_getoneofcase_field(msg, field) == field->number;
} else if (field->presence > 0) {
return _upb_hasbit_field(msg, field);
} else {
UPB_ASSERT(field->descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE ||
field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP);
return _upb_msg_getraw(msg, f).msg_val != NULL;
}
}
}
@ -136,73 +141,92 @@ const upb_fielddef *upb_msg_whichoneof(const upb_msg *msg,
}
upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) {
if (!upb_fielddef_haspresence(f) || upb_msg_has(msg, f)) {
if (upb_fielddef_isextension(f)) {
const upb_msg_ext *ext = _upb_msg_getext(msg, _upb_fielddef_extlayout(f));
if (ext) {
upb_msgval val;
memcpy(&val, &ext->data, sizeof(val));
return val;
} else if (upb_fielddef_isseq(f)) {
return (upb_msgval){.array_val = NULL};
}
} else if (!upb_fielddef_haspresence(f) || upb_msg_has(msg, f)) {
return _upb_msg_getraw(msg, f);
} else {
return upb_fielddef_default(f);
}
return upb_fielddef_default(f);
}
upb_mutmsgval upb_msg_mutable(upb_msg *msg, const upb_fielddef *f,
upb_arena *a) {
const upb_msglayout_field *field = upb_fielddef_layout(f);
upb_mutmsgval ret;
char *mem = UPB_PTR_AT(msg, field->offset, char);
bool wrong_oneof =
in_oneof(field) && _upb_getoneofcase_field(msg, field) != field->number;
assert(upb_fielddef_issubmsg(f) || upb_fielddef_isseq(f));
if (upb_fielddef_haspresence(f) && !upb_msg_has(msg, f)) {
// We need to skip the upb_msg_get() call in this case.
goto make;
}
memcpy(&ret, mem, sizeof(void*));
upb_msgval val = upb_msg_get(msg, f);
if (val.array_val) {
return (upb_mutmsgval){.array = (upb_array*)val.array_val};
}
if (a && (!ret.msg || wrong_oneof)) {
if (upb_fielddef_ismap(f)) {
const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
const upb_fielddef *key = upb_msgdef_itof(entry, UPB_MAPENTRY_KEY);
const upb_fielddef *value = upb_msgdef_itof(entry, UPB_MAPENTRY_VALUE);
ret.map = upb_map_new(a, upb_fielddef_type(key), upb_fielddef_type(value));
} else if (upb_fielddef_isseq(f)) {
ret.array = upb_array_new(a, upb_fielddef_type(f));
} else {
UPB_ASSERT(upb_fielddef_issubmsg(f));
ret.msg = upb_msg_new(upb_fielddef_msgsubdef(f), a);
}
upb_mutmsgval ret;
make:
if (!a) return (upb_mutmsgval){.array = NULL};
if (upb_fielddef_ismap(f)) {
const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
const upb_fielddef *key = upb_msgdef_itof(entry, UPB_MAPENTRY_KEY);
const upb_fielddef *value = upb_msgdef_itof(entry, UPB_MAPENTRY_VALUE);
ret.map = upb_map_new(a, upb_fielddef_type(key), upb_fielddef_type(value));
} else if (upb_fielddef_isseq(f)) {
ret.array = upb_array_new(a, upb_fielddef_type(f));
} else {
UPB_ASSERT(upb_fielddef_issubmsg(f));
ret.msg = upb_msg_new(upb_fielddef_msgsubdef(f), a);
}
memcpy(mem, &ret, sizeof(void*));
val.array_val = ret.array;
upb_msg_set(msg, f, val, a);
if (wrong_oneof) {
*_upb_oneofcase_field(msg, field) = field->number;
} else if (field->presence > 0) {
_upb_sethas_field(msg, field);
}
}
return ret;
}
void upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val,
bool upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val,
upb_arena *a) {
const upb_msglayout_field *field = upb_fielddef_layout(f);
char *mem = UPB_PTR_AT(msg, field->offset, char);
UPB_UNUSED(a); /* We reserve the right to make set insert into a map. */
memcpy(mem, &val, get_field_size(field));
if (field->presence > 0) {
_upb_sethas_field(msg, field);
} else if (in_oneof(field)) {
*_upb_oneofcase_field(msg, field) = field->number;
if (upb_fielddef_isextension(f)) {
upb_msg_ext *ext =
_upb_msg_getorcreateext(msg, _upb_fielddef_extlayout(f), a);
if (!ext) return false;
memcpy(&ext->data, &val, sizeof(val));
} else {
const upb_msglayout_field *field = upb_fielddef_layout(f);
char *mem = UPB_PTR_AT(msg, field->offset, char);
memcpy(mem, &val, get_field_size(field));
if (field->presence > 0) {
_upb_sethas_field(msg, field);
} else if (in_oneof(field)) {
*_upb_oneofcase_field(msg, field) = field->number;
}
}
return true;
}
void upb_msg_clearfield(upb_msg *msg, const upb_fielddef *f) {
const upb_msglayout_field *field = upb_fielddef_layout(f);
char *mem = UPB_PTR_AT(msg, field->offset, char);
if (field->presence > 0) {
_upb_clearhas_field(msg, field);
} else if (in_oneof(field)) {
uint32_t *oneof_case = _upb_oneofcase_field(msg, field);
if (*oneof_case != field->number) return;
*oneof_case = 0;
}
if (upb_fielddef_isextension(f)) {
_upb_msg_clearext(msg, _upb_fielddef_extlayout(f));
} else {
const upb_msglayout_field *field = upb_fielddef_layout(f);
char *mem = UPB_PTR_AT(msg, field->offset, char);
if (field->presence > 0) {
_upb_clearhas_field(msg, field);
} else if (in_oneof(field)) {
uint32_t *oneof_case = _upb_oneofcase_field(msg, field);
if (*oneof_case != field->number) return;
*oneof_case = 0;
}
memset(mem, 0, get_field_size(field));
memset(mem, 0, get_field_size(field));
}
}
void upb_msg_clear(upb_msg *msg, const upb_msgdef *m) {
@ -212,10 +236,12 @@ void upb_msg_clear(upb_msg *msg, const upb_msgdef *m) {
bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m,
const upb_symtab *ext_pool, const upb_fielddef **out_f,
upb_msgval *out_val, size_t *iter) {
int i = *iter;
int n = upb_msgdef_fieldcount(m);
size_t i = *iter;
size_t n = upb_msgdef_fieldcount(m);
const upb_msgval zero = {0};
UPB_UNUSED(ext_pool);
/* Iterate over normal fields, returning the first one that is set. */
while (++i < n) {
const upb_fielddef *f = upb_msgdef_field(m, i);
upb_msgval val = _upb_msg_getraw(msg, f);
@ -245,6 +271,20 @@ bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m,
*iter = i;
return true;
}
if (ext_pool) {
/* Return any extensions that are set. */
size_t count;
const upb_msg_ext *ext = _upb_msg_getexts(msg, &count);
if (i - n < count) {
ext += count - 1 - (i - n);
memcpy(out_val, &ext->data, sizeof(*out_val));
*out_f = _upb_symtab_lookupextfield(ext_pool, ext->ext);
*iter = i;
return true;
}
}
*iter = i;
return false;
}

@ -82,9 +82,10 @@ const upb_fielddef *upb_msg_whichoneof(const upb_msg *msg,
/* Sets the given field to the given value. For a msg/array/map/string, the
* value must be in the same arena. */
void upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val,
bool upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val,
upb_arena *a);
/* Clears any field presence and sets the value back to its default. */
void upb_msg_clearfield(upb_msg *msg, const upb_fielddef *f);

@ -54,6 +54,7 @@ cc_binary(
":common",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/strings",
"@com_google_protobuf//:protobuf",
"@com_google_protobuf//:protoc_lib",

@ -31,14 +31,6 @@ namespace {
namespace protobuf = ::google::protobuf;
void AddMessages(const protobuf::Descriptor* message,
std::vector<const protobuf::Descriptor*>* messages) {
messages->push_back(message);
for (int i = 0; i < message->nested_type_count(); i++) {
AddMessages(message->nested_type(i), messages);
}
}
} // namespace
std::string StripExtension(absl::string_view fname) {
@ -69,21 +61,16 @@ void EmitFileWarning(const protobuf::FileDescriptor* file, Output& output) {
file->name());
}
std::vector<const protobuf::Descriptor*> SortedMessages(
const protobuf::FileDescriptor* file) {
std::vector<const protobuf::Descriptor*> messages;
for (int i = 0; i < file->message_type_count(); i++) {
AddMessages(file->message_type(i), &messages);
}
return messages;
}
std::string MessageName(const protobuf::Descriptor* descriptor) {
return ToCIdent(descriptor->full_name());
}
std::string MessageInit(const protobuf::Descriptor* descriptor) {
return MessageName(descriptor) + "_msginit";
std::string FileLayoutName(const google::protobuf::FileDescriptor* file) {
return ToCIdent(file->name()) + "_upb_file_layout";
}
std::string HeaderFilename(const google::protobuf::FileDescriptor* file) {
return StripExtension(file->name()) + ".upb.h";
}
} // namespace upbc

@ -82,10 +82,9 @@ std::string ToCIdent(absl::string_view str);
std::string ToPreproc(absl::string_view str);
void EmitFileWarning(const google::protobuf::FileDescriptor* file,
Output& output);
std::vector<const google::protobuf::Descriptor*> SortedMessages(
const google::protobuf::FileDescriptor* file);
std::string MessageInit(const google::protobuf::Descriptor* descriptor);
std::string MessageName(const google::protobuf::Descriptor* descriptor);
std::string FileLayoutName(const google::protobuf::FileDescriptor* file);
std::string HeaderFilename(const google::protobuf::FileDescriptor* file);
} // namespace upbc

@ -26,6 +26,7 @@
#include <memory>
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/ascii.h"
#include "absl/strings/substitute.h"
#include "google/protobuf/compiler/code_generator.h"
@ -42,14 +43,31 @@ namespace {
namespace protoc = ::google::protobuf::compiler;
namespace protobuf = ::google::protobuf;
std::string HeaderFilename(std::string proto_filename) {
return StripExtension(proto_filename) + ".upb.h";
std::string SourceFilename(const google::protobuf::FileDescriptor* file) {
return StripExtension(file->name()) + ".upb.c";
}
std::string SourceFilename(std::string proto_filename) {
return StripExtension(proto_filename) + ".upb.c";
std::string MessageInit(const protobuf::Descriptor* descriptor) {
return MessageName(descriptor) + "_msginit";
}
std::string ExtensionIdentBase(const protobuf::FieldDescriptor* ext) {
assert(ext->is_extension());
std::string ext_scope;
if (ext->extension_scope()) {
return MessageName(ext->extension_scope());
} else {
return ToCIdent(ext->file()->package());
}
}
std::string ExtensionLayout(const google::protobuf::FieldDescriptor* ext) {
return absl::StrCat(ExtensionIdentBase(ext), "_", ext->name(), "_ext");
}
const char *kMessagesInit = "messages_layout";
const char *kExtensionsInit = "extensions_layout";
void AddEnums(const protobuf::Descriptor* message,
std::vector<const protobuf::EnumDescriptor*>* enums) {
for (int i = 0; i < message->enum_type_count(); i++) {
@ -79,6 +97,56 @@ std::vector<const protobuf::EnumDescriptor*> SortedEnums(
return enums;
}
void AddMessages(const protobuf::Descriptor* message,
std::vector<const protobuf::Descriptor*>* messages) {
messages->push_back(message);
for (int i = 0; i < message->nested_type_count(); i++) {
AddMessages(message->nested_type(i), messages);
}
}
// Ordering must match upb/def.c!
//
// The ordering is significant because each upb_msgdef* will point at the
// corresponding upb_msglayout and we just iterate through the list without
// any search or lookup.
std::vector<const protobuf::Descriptor*> SortedMessages(
const protobuf::FileDescriptor* file) {
std::vector<const protobuf::Descriptor*> messages;
for (int i = 0; i < file->message_type_count(); i++) {
AddMessages(file->message_type(i), &messages);
}
return messages;
}
void AddExtensionsFromMessage(
const protobuf::Descriptor* message,
std::vector<const protobuf::FieldDescriptor*>* exts) {
for (int i = 0; i < message->extension_count(); i++) {
exts->push_back(message->extension(i));
}
for (int i = 0; i < message->nested_type_count(); i++) {
AddExtensionsFromMessage(message->nested_type(i), exts);
}
}
// Ordering must match upb/def.c!
//
// The ordering is significant because each upb_fielddef* will point at the
// corresponding upb_msglayout_ext and we just iterate through the list without
// any search or lookup.
std::vector<const protobuf::FieldDescriptor*> SortedExtensions(
const protobuf::FileDescriptor* file) {
std::vector<const protobuf::FieldDescriptor*> ret;
for (int i = 0; i < file->message_type_count(); i++) {
AddExtensionsFromMessage(file->message_type(i), &ret);
}
for (int i = 0; i < file->extension_count(); i++) {
ret.push_back(file->extension(i));
}
return ret;
}
std::vector<const protobuf::FieldDescriptor*> FieldNumberOrder(
const protobuf::Descriptor* message) {
std::vector<const protobuf::FieldDescriptor*> fields;
@ -180,6 +248,29 @@ std::string SizeLg2(const protobuf::FieldDescriptor* field) {
}
}
std::string SizeRep(const protobuf::FieldDescriptor* field) {
switch (field->cpp_type()) {
case protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
return "_UPB_REP_PTR";
case protobuf::FieldDescriptor::CPPTYPE_ENUM:
case protobuf::FieldDescriptor::CPPTYPE_FLOAT:
case protobuf::FieldDescriptor::CPPTYPE_INT32:
case protobuf::FieldDescriptor::CPPTYPE_UINT32:
return "_UPB_REP_4BYTE";
case protobuf::FieldDescriptor::CPPTYPE_BOOL:
return "_UPB_REP_1BYTE";
case protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
case protobuf::FieldDescriptor::CPPTYPE_INT64:
case protobuf::FieldDescriptor::CPPTYPE_UINT64:
return "_UPB_REP_8BYTE";
case protobuf::FieldDescriptor::CPPTYPE_STRING:
return "_UPB_REP_STRVIEW";
default:
fprintf(stderr, "Unexpected type");
abort();
}
}
std::string FieldDefault(const protobuf::FieldDescriptor* field) {
switch (field->cpp_type()) {
case protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
@ -239,6 +330,34 @@ void DumpEnumValues(const protobuf::EnumDescriptor* desc, Output& output) {
}
}
void GenerateExtensionInHeader(const protobuf::FieldDescriptor* ext,
Output& output) {
output(
"UPB_INLINE bool $0_has_$1(const struct $2 *msg) { "
"return _upb_msg_getext(msg, &$3) != NULL; }\n",
ExtensionIdentBase(ext), ext->name(), MessageName(ext->containing_type()),
ExtensionLayout(ext));
if (ext->is_repeated()) {
} else if (ext->message_type()) {
output(
"UPB_INLINE $0 $1_$2(const struct $3 *msg) { "
"const upb_msg_ext *ext = _upb_msg_getext(msg, &$4); "
"UPB_ASSERT(ext); return *UPB_PTR_AT(&ext->data, 0, $0); }\n",
CTypeConst(ext), ExtensionIdentBase(ext), ext->name(),
MessageName(ext->containing_type()), ExtensionLayout(ext),
FieldDefault(ext));
} else {
output(
"UPB_INLINE $0 $1_$2(const struct $3 *msg) { "
"const upb_msg_ext *ext = _upb_msg_getext(msg, &$4); "
"return ext ? *UPB_PTR_AT(&ext->data, 0, $0) : $5; }\n",
CTypeConst(ext), ExtensionIdentBase(ext), ext->name(),
MessageName(ext->containing_type()), ExtensionLayout(ext),
FieldDefault(ext));
}
}
void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output) {
MessageLayout layout(message);
@ -524,11 +643,10 @@ void WriteHeader(const protobuf::FileDescriptor* file, Output& output) {
ToPreproc(file->name()));
for (int i = 0; i < file->public_dependency_count(); i++) {
const auto& name = file->public_dependency(i)->name();
if (i == 0) {
output("/* Public Imports. */\n");
}
output("#include \"$0\"\n", HeaderFilename(name));
output("#include \"$0\"\n", HeaderFilename(file));
if (i == file->public_dependency_count() - 1) {
output("\n");
}
@ -544,6 +662,8 @@ void WriteHeader(const protobuf::FileDescriptor* file, Output& output) {
const std::vector<const protobuf::Descriptor*> this_file_messages =
SortedMessages(file);
const std::vector<const protobuf::FieldDescriptor*> this_file_exts =
SortedExtensions(file);
// Forward-declare types defined in this file.
for (auto message : this_file_messages) {
@ -555,6 +675,9 @@ void WriteHeader(const protobuf::FileDescriptor* file, Output& output) {
for (auto message : this_file_messages) {
output("extern const upb_msglayout $0;\n", MessageInit(message));
}
for (auto ext : this_file_exts) {
output("extern const upb_msglayout_ext $0;\n", ExtensionLayout(ext));
}
// Forward-declare types not in this file, but used as submessages.
// Order by full name for consistent ordering.
@ -570,6 +693,12 @@ void WriteHeader(const protobuf::FileDescriptor* file, Output& output) {
}
}
}
for (auto ext : this_file_exts) {
if (ext->file() != ext->containing_type()->file()) {
forward_messages[ext->containing_type()->full_name()] =
ext->containing_type();
}
}
for (const auto& pair : forward_messages) {
output("struct $0;\n", MessageName(pair.second));
}
@ -596,6 +725,12 @@ void WriteHeader(const protobuf::FileDescriptor* file, Output& output) {
GenerateMessageInHeader(message, output);
}
for (auto ext : this_file_exts) {
GenerateExtensionInHeader(ext, output);
}
output("extern const upb_msglayout_file $0;\n\n", FileLayoutName(file));
output(
"#ifdef __cplusplus\n"
"} /* extern \"C\" */\n"
@ -853,20 +988,28 @@ void WriteField(const protobuf::FieldDescriptor* field,
absl::string_view offset, absl::string_view presence,
int submsg_index, Output& output) {
std::string mode;
std::string rep;
if (field->is_map()) {
mode = "_UPB_MODE_MAP";
rep = "_UPB_REP_PTR";
} else if (field->is_repeated()) {
mode = "_UPB_MODE_ARRAY";
rep = "_UPB_REP_PTR";
} else {
mode = "_UPB_MODE_SCALAR";
rep = SizeRep(field);
}
if (field->is_packed()) {
absl::StrAppend(&mode, " | _UPB_MODE_IS_PACKED");
}
output("{$0, $1, $2, $3, $4, $5}", field->number(), offset, presence,
submsg_index, TableDescriptorType(field), mode);
if (field->is_extension()) {
absl::StrAppend(&mode, " | _UPB_MODE_IS_EXTENSION");
}
output("{$0, $1, $2, $3, $4, $5 | ($6 << 6)}", field->number(), offset,
presence, submsg_index, TableDescriptorType(field), mode, rep);
}
// Writes a single field into a .upb.c source file.
@ -913,11 +1056,11 @@ void WriteMessage(const protobuf::Descriptor* message, Output& output,
// "submsgs" array for every strongly-connected component.
std::string submsgs_array_name = msg_name + "_submsgs";
submsgs_array_ref = "&" + submsgs_array_name + "[0]";
output("static const upb_msglayout *const $0[$1] = {\n",
output("static const upb_msglayout_sub $0[$1] = {\n",
submsgs_array_name, submsg_array.submsgs().size());
for (auto submsg : submsg_array.submsgs()) {
output(" &$0,\n", MessageInit(submsg));
output(" {.submsg = &$0},\n", MessageInit(submsg));
}
output("};\n\n");
@ -960,12 +1103,19 @@ void WriteMessage(const protobuf::Descriptor* message, Output& output,
table_mask = (table.size() - 1) << 3;
}
std::string msgext = "_UPB_MSGEXT_NONE";
if (message->extension_range_count()) {
msgext = "_UPB_MSGEXT_EXTENDABLE";
}
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", GetSizeInit(layout.message_size()),
output(" $0, $1, $2, $3, $4,\n",
GetSizeInit(layout.message_size()),
field_number_order.size(),
"false", // TODO: extendable
msgext,
dense_below,
table_mask
);
@ -980,11 +1130,74 @@ void WriteMessage(const protobuf::Descriptor* message, Output& output,
output("};\n\n");
}
void WriteMessages(const protobuf::FileDescriptor* file, Output& output,
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) {
for (auto* message : SortedMessages(file)) {
std::vector<const protobuf::Descriptor*> file_messages =
SortedMessages(file);
if (file_messages.empty()) return 0;
for (auto message : file_messages) {
WriteMessage(message, output, fasttable_enabled);
}
output("static const upb_msglayout *$0[$1] = {\n", kMessagesInit,
file_messages.size());
for (auto message : file_messages) {
output(" &$0,\n", MessageInit(message));
}
output("};\n");
output("\n");
return file_messages.size();
}
int WriteExtensions(const protobuf::FileDescriptor* file, Output& output) {
auto exts = SortedExtensions(file);
absl::flat_hash_set<const protobuf::Descriptor*> forward_decls;
if (exts.empty()) return 0;
for (auto ext : exts) {
forward_decls.insert(ext->containing_type());
if (ext->message_type()) {
forward_decls.insert(ext->message_type());
}
}
for (auto ext : exts) {
WriteExtension(ext, output);
}
for (auto decl : forward_decls) {
output("extern const upb_msglayout $0;\n", MessageInit(decl));
}
output(
"\n"
"static const upb_msglayout_ext *$0[$1] = {\n",
kExtensionsInit, exts.size());
for (auto ext : exts) {
output(" &$0,\n", ExtensionLayout(ext));
}
output(
"};\n"
"\n");
return exts.size();
}
// Writes a .upb.c source file.
@ -996,10 +1209,10 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output,
"#include <stddef.h>\n"
"#include \"upb/msg_internal.h\"\n"
"#include \"$0\"\n",
HeaderFilename(file->name()));
HeaderFilename(file));
for (int i = 0; i < file->dependency_count(); i++) {
output("#include \"$0\"\n", HeaderFilename(file->dependency(i)->name()));
output("#include \"$0\"\n", HeaderFilename(file->dependency(i)));
}
output(
@ -1007,7 +1220,15 @@ void WriteSource(const protobuf::FileDescriptor* file, Output& output,
"#include \"upb/port_def.inc\"\n"
"\n");
WriteMessages(file, output, fasttable_enabled);
int msg_count = WriteMessages(file, output, fasttable_enabled);
int ext_count = WriteExtensions(file, output);
output("const upb_msglayout_file $0 = {\n", FileLayoutName(file));
output(" $0,\n", msg_count ? kMessagesInit : "NULL");
output(" $0,\n", ext_count ? kExtensionsInit : "NULL");
output(" $0,\n", msg_count);
output(" $0,\n", ext_count);
output("};\n\n");
output("#include \"upb/port_undef.inc\"\n");
output("\n");
@ -1040,10 +1261,10 @@ bool Generator::Generate(const protobuf::FileDescriptor* file,
}
}
Output h_output(context->Open(HeaderFilename(file->name())));
Output h_output(context->Open(HeaderFilename(file)));
WriteHeader(file, h_output);
Output c_output(context->Open(SourceFilename(file->name())));
Output c_output(context->Open(SourceFilename(file)));
WriteSource(file, c_output, fasttable_enabled);
return true;

@ -104,29 +104,13 @@ void WriteDefSource(const protobuf::FileDescriptor* file, Output& output) {
output("#include \"upb/def.h\"\n");
output("#include \"$0\"\n", DefHeaderFilename(file->name()));
output("#include \"$0\"\n", HeaderFilename(file));
output("\n");
for (int i = 0; i < file->dependency_count(); i++) {
output("extern upb_def_init $0;\n", DefInitSymbol(file->dependency(i)));
}
std::vector<const protobuf::Descriptor*> file_messages =
SortedMessages(file);
for (auto message : file_messages) {
output("extern const upb_msglayout $0;\n", MessageInit(message));
}
output("\n");
if (!file_messages.empty()) {
output("static const upb_msglayout *layouts[$0] = {\n", file_messages.size());
for (auto message : file_messages) {
output(" &$0,\n", MessageInit(message));
}
output("};\n");
output("\n");
}
protobuf::FileDescriptorProto file_proto;
file->CopyTo(&file_proto);
std::string file_data;
@ -156,11 +140,7 @@ void WriteDefSource(const protobuf::FileDescriptor* file, Output& output) {
output("upb_def_init $0 = {\n", DefInitSymbol(file));
output(" deps,\n");
if (file_messages.empty()) {
output(" NULL,\n");
} else {
output(" layouts,\n");
}
output(" &$0,\n", FileLayoutName(file));
output(" \"$0\",\n", file->name());
output(" UPB_STRVIEW_INIT(descriptor, $0)\n", file_data.size());
output("};\n");

Loading…
Cancel
Save