From cdd6434a31bc4f51081d4ecb14dd8d114c45647e Mon Sep 17 00:00:00 2001 From: Joshua Haberman Date: Tue, 1 Jun 2021 17:20:01 -0700 Subject: [PATCH] Introduced upb_extreg and plumbed it into decoder. --- benchmarks/benchmark.cc | 4 +- cmake/google/protobuf/descriptor.upb.h | 351 +++++++++++++++++-------- upb/bindings/lua/msg.c | 2 +- upb/decode.c | 3 +- upb/decode.h | 5 +- upb/def.c | 3 +- upb/msg.c | 53 ++++ upb/msg.h | 42 +++ upb/msg_internal.h | 14 + upbc/protoc-gen-upb.cc | 13 +- 10 files changed, 371 insertions(+), 119 deletions(-) diff --git a/benchmarks/benchmark.cc b/benchmarks/benchmark.cc index 601e8c7b00..178eb21dcd 100644 --- a/benchmarks/benchmark.cc +++ b/benchmarks/benchmark.cc @@ -162,8 +162,8 @@ static void BM_Parse_Upb_FileDesc(benchmark::State& state) { } upb_benchmark_FileDescriptorProto* set = upb_benchmark_FileDescriptorProto_parse_ex( - descriptor.data, descriptor.size, arena, - Copy == Alias ? UPB_DECODE_ALIAS : 0); + descriptor.data, descriptor.size, NULL, + Copy == Alias ? UPB_DECODE_ALIAS : 0, arena); if (!set) { printf("Failed to parse.\n"); exit(1); diff --git a/cmake/google/protobuf/descriptor.upb.h b/cmake/google/protobuf/descriptor.upb.h index 4e2401b71c..44e263f512 100644 --- a/cmake/google/protobuf/descriptor.upb.h +++ b/cmake/google/protobuf/descriptor.upb.h @@ -162,13 +162,18 @@ UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_ UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_FileDescriptorSet *ret = google_protobuf_FileDescriptorSet_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_FileDescriptorSet *ret = google_protobuf_FileDescriptorSet_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_FileDescriptorSet_serialize(const google_protobuf_FileDescriptorSet *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_FileDescriptorSet_msginit, arena, len); @@ -199,13 +204,18 @@ UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorPr UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_FileDescriptorProto *ret = google_protobuf_FileDescriptorProto_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_FileDescriptorProto *ret = google_protobuf_FileDescriptorProto_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_FileDescriptorProto_serialize(const google_protobuf_FileDescriptorProto *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_FileDescriptorProto_msginit, arena, len); @@ -362,13 +372,18 @@ UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_new( UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_DescriptorProto *ret = google_protobuf_DescriptorProto_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_DescriptorProto *ret = google_protobuf_DescriptorProto_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_DescriptorProto_serialize(const google_protobuf_DescriptorProto *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_DescriptorProto_msginit, arena, len); @@ -521,13 +536,18 @@ UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_Descr UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_DescriptorProto_ExtensionRange *ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_DescriptorProto_ExtensionRange *ret = google_protobuf_DescriptorProto_ExtensionRange_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_DescriptorProto_ExtensionRange_serialize(const google_protobuf_DescriptorProto_ExtensionRange *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena, len); @@ -570,13 +590,18 @@ UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_Descri UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_DescriptorProto_ReservedRange *ret = google_protobuf_DescriptorProto_ReservedRange_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_DescriptorProto_ReservedRange *ret = google_protobuf_DescriptorProto_ReservedRange_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_DescriptorProto_ReservedRange_serialize(const google_protobuf_DescriptorProto_ReservedRange *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena, len); @@ -604,13 +629,18 @@ UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRange UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_ExtensionRangeOptions *ret = google_protobuf_ExtensionRangeOptions_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_ExtensionRangeOptions *ret = google_protobuf_ExtensionRangeOptions_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_ExtensionRangeOptions_serialize(const google_protobuf_ExtensionRangeOptions *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_ExtensionRangeOptions_msginit, arena, len); @@ -641,13 +671,18 @@ UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptor UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_FieldDescriptorProto *ret = google_protobuf_FieldDescriptorProto_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_FieldDescriptorProto *ret = google_protobuf_FieldDescriptorProto_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_FieldDescriptorProto_serialize(const google_protobuf_FieldDescriptorProto *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_FieldDescriptorProto_msginit, arena, len); @@ -738,13 +773,18 @@ UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptor UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_OneofDescriptorProto *ret = google_protobuf_OneofDescriptorProto_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_OneofDescriptorProto *ret = google_protobuf_OneofDescriptorProto_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_OneofDescriptorProto_serialize(const google_protobuf_OneofDescriptorProto *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_OneofDescriptorProto_msginit, arena, len); @@ -781,13 +821,18 @@ UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorPr UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_EnumDescriptorProto *ret = google_protobuf_EnumDescriptorProto_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_EnumDescriptorProto *ret = google_protobuf_EnumDescriptorProto_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_EnumDescriptorProto_serialize(const google_protobuf_EnumDescriptorProto *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_EnumDescriptorProto_msginit, arena, len); @@ -865,13 +910,18 @@ UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobu UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_EnumDescriptorProto_EnumReservedRange *ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_EnumDescriptorProto_EnumReservedRange *ret = google_protobuf_EnumDescriptorProto_EnumReservedRange_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_EnumDescriptorProto_EnumReservedRange_serialize(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena, len); @@ -899,13 +949,18 @@ UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDe UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_EnumValueDescriptorProto *ret = google_protobuf_EnumValueDescriptorProto_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_EnumValueDescriptorProto *ret = google_protobuf_EnumValueDescriptorProto_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_EnumValueDescriptorProto_serialize(const google_protobuf_EnumValueDescriptorProto *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_EnumValueDescriptorProto_msginit, arena, len); @@ -948,13 +1003,18 @@ UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescri UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_ServiceDescriptorProto *ret = google_protobuf_ServiceDescriptorProto_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_ServiceDescriptorProto *ret = google_protobuf_ServiceDescriptorProto_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_ServiceDescriptorProto_serialize(const google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_ServiceDescriptorProto_msginit, arena, len); @@ -1006,13 +1066,18 @@ UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescript UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_MethodDescriptorProto *ret = google_protobuf_MethodDescriptorProto_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_MethodDescriptorProto *ret = google_protobuf_MethodDescriptorProto_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_MethodDescriptorProto_serialize(const google_protobuf_MethodDescriptorProto *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_MethodDescriptorProto_msginit, arena, len); @@ -1073,13 +1138,18 @@ UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_new(upb_aren UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_FileOptions *ret = google_protobuf_FileOptions_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_FileOptions *ret = google_protobuf_FileOptions_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_FileOptions_serialize(const google_protobuf_FileOptions *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_FileOptions_msginit, arena, len); @@ -1230,13 +1300,18 @@ UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_new(up UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_MessageOptions *ret = google_protobuf_MessageOptions_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_MessageOptions *ret = google_protobuf_MessageOptions_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_MessageOptions_serialize(const google_protobuf_MessageOptions *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_MessageOptions_msginit, arena, len); @@ -1291,13 +1366,18 @@ UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_new(upb_ar UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_FieldOptions *ret = google_protobuf_FieldOptions_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_FieldOptions *ret = google_protobuf_FieldOptions_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_FieldOptions_serialize(const google_protobuf_FieldOptions *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_FieldOptions_msginit, arena, len); @@ -1364,13 +1444,18 @@ UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_new(upb_ar UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_OneofOptions *ret = google_protobuf_OneofOptions_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_OneofOptions *ret = google_protobuf_OneofOptions_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_OneofOptions_serialize(const google_protobuf_OneofOptions *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_OneofOptions_msginit, arena, len); @@ -1401,13 +1486,18 @@ UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_new(upb_aren UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_EnumOptions *ret = google_protobuf_EnumOptions_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_EnumOptions *ret = google_protobuf_EnumOptions_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_EnumOptions_serialize(const google_protobuf_EnumOptions *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_EnumOptions_msginit, arena, len); @@ -1450,13 +1540,18 @@ UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_ne UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_EnumValueOptions *ret = google_protobuf_EnumValueOptions_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_EnumValueOptions *ret = google_protobuf_EnumValueOptions_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_EnumValueOptions_serialize(const google_protobuf_EnumValueOptions *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_EnumValueOptions_msginit, arena, len); @@ -1493,13 +1588,18 @@ UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_new(up UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_ServiceOptions *ret = google_protobuf_ServiceOptions_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_ServiceOptions *ret = google_protobuf_ServiceOptions_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_ServiceOptions_serialize(const google_protobuf_ServiceOptions *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_ServiceOptions_msginit, arena, len); @@ -1536,13 +1636,18 @@ UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_new(upb_ UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_MethodOptions *ret = google_protobuf_MethodOptions_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_MethodOptions *ret = google_protobuf_MethodOptions_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_MethodOptions_serialize(const google_protobuf_MethodOptions *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_MethodOptions_msginit, arena, len); @@ -1585,13 +1690,18 @@ UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOpt UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_UninterpretedOption *ret = google_protobuf_UninterpretedOption_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_UninterpretedOption *ret = google_protobuf_UninterpretedOption_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_UninterpretedOption_serialize(const google_protobuf_UninterpretedOption *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_UninterpretedOption_msginit, arena, len); @@ -1658,13 +1768,18 @@ UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_Uninter UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_UninterpretedOption_NamePart *ret = google_protobuf_UninterpretedOption_NamePart_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_UninterpretedOption_NamePart *ret = google_protobuf_UninterpretedOption_NamePart_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_UninterpretedOption_NamePart_serialize(const google_protobuf_UninterpretedOption_NamePart *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_UninterpretedOption_NamePart_msginit, arena, len); @@ -1692,13 +1807,18 @@ UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_new(up UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_SourceCodeInfo *ret = google_protobuf_SourceCodeInfo_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_SourceCodeInfo *ret = google_protobuf_SourceCodeInfo_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_SourceCodeInfo_serialize(const google_protobuf_SourceCodeInfo *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_SourceCodeInfo_msginit, arena, len); @@ -1729,13 +1849,18 @@ UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeIn UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_SourceCodeInfo_Location *ret = google_protobuf_SourceCodeInfo_Location_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_SourceCodeInfo_Location *ret = google_protobuf_SourceCodeInfo_Location_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_SourceCodeInfo_Location_serialize(const google_protobuf_SourceCodeInfo_Location *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_SourceCodeInfo_Location_msginit, arena, len); @@ -1796,13 +1921,18 @@ UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_ UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_GeneratedCodeInfo *ret = google_protobuf_GeneratedCodeInfo_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_GeneratedCodeInfo *ret = google_protobuf_GeneratedCodeInfo_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_GeneratedCodeInfo_serialize(const google_protobuf_GeneratedCodeInfo *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_msginit, arena, len); @@ -1833,13 +1963,18 @@ UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_Generat UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_parse(const char *buf, size_t size, upb_arena *arena) { google_protobuf_GeneratedCodeInfo_Annotation *ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena); - return (ret && upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena)) ? ret : NULL; + if (!ret || !upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena)) return NULL; + return ret; } UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_parse_ex(const char *buf, size_t size, - upb_arena *arena, int options) { + const upb_extreg *extreg, int options, + upb_arena *arena) { google_protobuf_GeneratedCodeInfo_Annotation *ret = google_protobuf_GeneratedCodeInfo_Annotation_new(arena); - return (ret && _upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena, options)) - ? ret : NULL; + if (!ret) return NULL; + if (!_upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, extreg, options, arena)) { + return NULL; + } + return ret; } UPB_INLINE char *google_protobuf_GeneratedCodeInfo_Annotation_serialize(const google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_arena *arena, size_t *len) { return upb_encode(msg, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena, len); diff --git a/upb/bindings/lua/msg.c b/upb/bindings/lua/msg.c index 4b5db2bf2e..6210e39493 100644 --- a/upb/bindings/lua/msg.c +++ b/upb/bindings/lua/msg.c @@ -949,7 +949,7 @@ static int lupb_decode(lua_State *L) { buf = upb_arena_malloc(arena, len); memcpy(buf, pb, len); - ok = _upb_decode(buf, len, msg, layout, arena, UPB_DECODE_ALIAS); + ok = _upb_decode(buf, len, msg, layout, NULL, UPB_DECODE_ALIAS, arena); if (!ok) { lua_pushstring(L, "Error decoding protobuf."); diff --git a/upb/decode.c b/upb/decode.c index 1bd091ec9f..2739be86e7 100644 --- a/upb/decode.c +++ b/upb/decode.c @@ -722,7 +722,8 @@ static bool decode_top(struct upb_decstate *d, const char *buf, void *msg, } bool _upb_decode(const char *buf, size_t size, void *msg, - const upb_msglayout *l, upb_arena *arena, int options) { + const upb_msglayout *l, const upb_extreg *extreg, int options, + upb_arena *arena) { bool ok; upb_decstate state; unsigned depth = (unsigned)options >> 16; diff --git a/upb/decode.h b/upb/decode.h index 7114944e20..24008910c0 100644 --- a/upb/decode.h +++ b/upb/decode.h @@ -50,12 +50,13 @@ enum { #define UPB_DECODE_MAXDEPTH(depth) ((depth) << 16) bool _upb_decode(const char *buf, size_t size, upb_msg *msg, - const upb_msglayout *l, upb_arena *arena, int options); + const upb_msglayout *l, const upb_extreg *extreg, int options, + upb_arena *arena); UPB_INLINE bool upb_decode(const char *buf, size_t size, upb_msg *msg, const upb_msglayout *l, upb_arena *arena) { - return _upb_decode(buf, size, msg, l, arena, 0); + return _upb_decode(buf, size, msg, l, NULL, 0, arena); } #ifdef __cplusplus diff --git a/upb/def.c b/upb/def.c index 599f42e5be..641f1b428b 100644 --- a/upb/def.c +++ b/upb/def.c @@ -2132,7 +2132,8 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) { } file = google_protobuf_FileDescriptorProto_parse_ex( - init->descriptor.data, init->descriptor.size, arena, UPB_DECODE_ALIAS); + init->descriptor.data, init->descriptor.size, NULL, UPB_DECODE_ALIAS, + arena); s->bytes_loaded += init->descriptor.size; if (!file) { diff --git a/upb/msg.c b/upb/msg.c index 5ecacb8dfd..2d76443bba 100644 --- a/upb/msg.c +++ b/upb/msg.c @@ -338,3 +338,56 @@ bool _upb_mapsorter_pushmap(_upb_mapsorter *s, upb_descriptortype_t key_type, qsort(&s->entries[sorted->start], map_size, sizeof(*s->entries), compar); return true; } + +/** upb_extreg ****************************************************************/ + +struct upb_extreg { + upb_arena *arena; + upb_strtable exts; /* Key is upb_msglayout* concatenated with fieldnum. */ +}; + +#define EXTREG_KEY_SIZE (sizeof(upb_msglayout*) + sizeof(uint32_t)) + +static void extreg_key(char *buf, const upb_msglayout *l, uint32_t fieldnum) { + memcpy(buf, &l, sizeof(l)); + memcpy(buf + sizeof(l), &fieldnum, sizeof(fieldnum)); +} + +upb_extreg *upb_extreg_new(upb_arena *arena) { + upb_extreg *r = upb_arena_malloc(arena, sizeof(*r)); + if (!r) return NULL; + r->arena = arena; + if (!upb_strtable_init(&r->exts, 8, arena)) return NULL; + return r; +} + +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; + for (const upb_msglayout_ext *end = e + count; e < end; e++) { + extreg_key(buf, e->extendee, e->field.number); + if (!upb_strtable_insert(&r->exts, buf, EXTREG_KEY_SIZE, + upb_value_constptr(e), r->arena)) { + /* Back out the entries previously added. */ + for (end = e, e = start; e < end; e++) { + extreg_key(buf, e->extendee, e->field.number); + upb_strtable_remove(&r->exts, buf, EXTREG_KEY_SIZE, NULL); + } + return false; + } + } + return true; +} + +const upb_msglayout_field *_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); + if (upb_strtable_lookup2(&r->exts, buf, EXTREG_KEY_SIZE, &v)) { + return upb_value_getconstptr(v); + } else { + return NULL; + } +} diff --git a/upb/msg.h b/upb/msg.h index b3dea4dc9e..497bd82b01 100644 --- a/upb/msg.h +++ b/upb/msg.h @@ -59,6 +59,48 @@ void upb_msg_addunknown(upb_msg *msg, const char *data, size_t len, /* Returns a reference to the message's unknown data. */ const char *upb_msg_getunknown(const upb_msg *msg, size_t *len); +/** upb_extreg *******************************************************************/ + +/* Extension registry: a dynamic data structure that stores a map of: + * (upb_msglayout, number) -> extension info + * + * upb_decode() uses upb_extreg to look up extensions while parsing binary + * format. + * + * upb_extreg is part of the mini-table (msglayout) family of objects. Like all + * mini-table objects, it is suitable for reflection-less builds that do not + * want to expose names into the binary. + * + * Unlike most mini-table types, upb_extreg requires dynamic memory allocation + * and dynamic initialization: + * * If reflection is being used, then upb_symtab will construct an appropriate + * upb_extreg automatically. + * * For a mini-table only build, the user must manually construct the + * upb_extreg and populate it with all of the extensions the user cares about. + * * A third alternative is to manually unpack relevant extensions after the + * main parse is complete, similar to how Any works. This is perhaps the + * nicest solution from the perspective of reducing dependencies, avoiding + * dynamic memory allocation, and avoiding the need to parse uninteresting + * extensions. The downsides are: + * (1) parse errors are not caught during the main parse + * (2) the CPU hit of parsing comes during access, which could cause an + * undesirable stutter in application performance. + * + * Users cannot directly get or put into this map. Users can only add the + * extensions from a generated module and pass the extension registry to the + * binary decoder. + * + * A upb_symtab provides a upb_extreg, so any users who use reflection do not + * need to populate a upb_extreg directly. + */ + +struct upb_extreg; +typedef struct upb_extreg upb_extreg; + +/* Creates a upb_extreg in the given arena. The arena must outlive any use of + * the extreg. */ +upb_extreg *upb_extreg_new(upb_arena *arena); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/upb/msg_internal.h b/upb/msg_internal.h index 016782f56c..24517002ea 100644 --- a/upb/msg_internal.h +++ b/upb/msg_internal.h @@ -103,6 +103,20 @@ typedef struct { const upb_msglayout *submsg; /* NULL for non-submessage fields. */ } upb_msglayout_ext; +/** 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); + +/* 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); + /** upb_msg *******************************************************************/ /* Internal members of a upb_msg that track unknown fields and/or extensions. diff --git a/upbc/protoc-gen-upb.cc b/upbc/protoc-gen-upb.cc index 79db357dd3..7c11af2db4 100644 --- a/upbc/protoc-gen-upb.cc +++ b/upbc/protoc-gen-upb.cc @@ -253,13 +253,18 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output "UPB_INLINE $0 *$0_parse(const char *buf, size_t size,\n" " upb_arena *arena) {\n" " $0 *ret = $0_new(arena);\n" - " return (ret && upb_decode(buf, size, ret, &$1, arena)) ? ret : NULL;\n" + " if (!ret || !upb_decode(buf, size, ret, &$1, arena)) return NULL;\n" + " return ret;\n" "}\n" "UPB_INLINE $0 *$0_parse_ex(const char *buf, size_t size,\n" - " upb_arena *arena, int options) {\n" + " const upb_extreg *extreg, int options,\n" + " upb_arena *arena) {\n" " $0 *ret = $0_new(arena);\n" - " return (ret && _upb_decode(buf, size, ret, &$1, arena, options))\n" - " ? ret : NULL;\n" + " if (!ret) return NULL;\n" + " if (!_upb_decode(buf, size, ret, &$1, extreg, options, arena)) {\n" + " return NULL;\n" + " }\n" + " return ret;\n" "}\n" "UPB_INLINE char *$0_serialize(const $0 *msg, upb_arena *arena, size_t " "*len) {\n"