Merge pull request #400 from haberman/extreg

Introduced upb_extreg and plumbed it into decoder.
pull/13171/head
Joshua Haberman 4 years ago committed by GitHub
commit f925acf5f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      benchmarks/benchmark.cc
  2. 378
      cmake/google/protobuf/descriptor.upb.h
  3. 2
      upb/bindings/lua/msg.c
  4. 3
      upb/decode.c
  5. 5
      upb/decode.h
  6. 3
      upb/def.c
  7. 57
      upb/msg.c
  8. 42
      upb/msg.h
  9. 14
      upb/msg_internal.h
  10. 14
      upbc/protoc-gen-upb.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);

@ -162,13 +162,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_parse_ex(const char *buf, size_t size,
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 +205,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_parse_ex(const char *buf, size_t size,
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 +374,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_parse_ex(const char *buf, size_t size,
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 +539,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ExtensionRange_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_parse_ex(const char *buf, size_t size,
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 +594,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_ReservedRange_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_parse_ex(const char *buf, size_t size,
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 +634,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_parse_ex(const char *buf, size_t size,
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 +677,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_parse_ex(const char *buf, size_t size,
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 +780,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_parse_ex(const char *buf, size_t size,
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 +829,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_parse_ex(const char *buf, size_t size,
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 +919,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_parse_ex(const char *buf, size_t size,
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 +959,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_parse_ex(const char *buf, size_t size,
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 +1014,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_parse_ex(const char *buf, size_t size,
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 +1078,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_parse_ex(const char *buf, size_t size,
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 +1151,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parse_ex(const char *buf, size_t size,
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 +1314,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parse_ex(const char *buf, size_t size,
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 +1381,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parse_ex(const char *buf, size_t size,
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 +1460,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parse_ex(const char *buf, size_t size,
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 +1503,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parse_ex(const char *buf, size_t size,
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 +1558,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_parse_ex(const char *buf, size_t size,
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 +1607,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parse_ex(const char *buf, size_t size,
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 +1656,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parse_ex(const char *buf, size_t size,
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 +1711,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_parse_ex(const char *buf, size_t size,
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 +1790,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_NamePart_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_parse_ex(const char *buf, size_t size,
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 +1830,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parse_ex(const char *buf, size_t size,
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 +1873,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_Location_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_parse_ex(const char *buf, size_t size,
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 +1946,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_parse_ex(const char *buf, size_t size,
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 +1989,19 @@ 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) return NULL;
if (!upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena)) return NULL;
return ret;
}
UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_parse_ex(const char *buf, size_t size,
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);

@ -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.");

@ -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;

@ -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

@ -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) {

@ -338,3 +338,60 @@ 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;
const upb_msglayout_ext *end = e + count;
for (; 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)) {
goto failure;
}
}
return true;
failure:
/* 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;
}
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;
}
}

@ -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

@ -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.

@ -253,13 +253,19 @@ 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) return NULL;\n"
" if (!upb_decode(buf, size, ret, &$1, arena)) return NULL;\n"
" return ret;\n"
"}\n"
"UPB_INLINE $0 *$0_parse_ex(const char *buf, size_t size,\n"
" 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"

Loading…
Cancel
Save