diff --git a/bazel/upb_proto_library.bzl b/bazel/upb_proto_library.bzl index d4d51604f4..bec5d9cbd1 100644 --- a/bazel/upb_proto_library.bzl +++ b/bazel/upb_proto_library.bzl @@ -21,23 +21,17 @@ def _get_real_short_path(file): # Sometimes it has another few prefixes like: # _virtual_imports/any_proto/google/protobuf/any.proto + # benchmarks/_virtual_imports/100_msgs_proto/benchmarks/100_msgs.proto # We want just google/protobuf/any.proto. - if short_path.startswith("_virtual_imports"): - short_path = short_path.split("/", 2)[-1] + virtual_imports = "_virtual_imports/" + if virtual_imports in short_path: + short_path = short_path.split(virtual_imports)[1].split("/", 1)[1] return short_path def _get_real_root(file): real_short_path = _get_real_short_path(file) return file.path[:-len(real_short_path) - 1] -def _get_real_roots(files): - roots = {} - for file in files: - real_root = _get_real_root(file) - if real_root: - roots[real_root] = True - return roots.keys() - def _generate_output_file(ctx, src, extension): real_short_path = _get_real_short_path(src) real_short_path = paths.relativize(real_short_path, ctx.label.package) diff --git a/benchmarks/BUILD b/benchmarks/BUILD index 3e06fff8a2..720f8c681b 100644 --- a/benchmarks/BUILD +++ b/benchmarks/BUILD @@ -3,22 +3,29 @@ load( "upb_proto_library", "upb_proto_reflection_library", ) +load( + ":build_defs.bzl", + "tmpl_cc_binary", + "cc_lite_proto_library", + "expand_suffixes", + "proto_library", +) licenses(["notice"]) proto_library( - name = "benchmark_descriptor_proto", + name = "descriptor_proto", srcs = ["descriptor.proto"], ) upb_proto_library( name = "benchmark_descriptor_upb_proto", - deps = [":benchmark_descriptor_proto"], + deps = [":descriptor_proto"], ) upb_proto_reflection_library( name = "benchmark_descriptor_upb_proto_reflection", - deps = [":benchmark_descriptor_proto"], + deps = [":descriptor_proto"], ) upb_proto_reflection_library( @@ -28,7 +35,7 @@ upb_proto_reflection_library( cc_proto_library( name = "benchmark_descriptor_cc_proto", - deps = [":benchmark_descriptor_proto"], + deps = [":descriptor_proto"], ) proto_library( @@ -58,3 +65,134 @@ cc_binary( "@com_google_protobuf//:protobuf", ], ) + +# Size benchmarks. + +SIZE_BENCHMARKS = { + "empty": "Empty", + "descriptor": "FileDescriptorSet", + "100_msgs": "Message100", + "200_msgs": "Message200", + "100_fields": "Message", + "200_fields": "Message", +} + +py_binary( + name = "gen_synthetic_protos", + srcs = ["gen_synthetic_protos.py"], + python_version = "PY3", +) + +py_binary( + name = "gen_upb_binary_c", + srcs = ["gen_upb_binary_c.py"], + python_version = "PY3", +) + +py_binary( + name = "gen_protobuf_binary_cc", + srcs = ["gen_protobuf_binary_cc.py"], + python_version = "PY3", +) + +genrule( + name = "do_gen_synthetic_protos", + tools = [":gen_synthetic_protos"], + outs = [ + "100_msgs.proto", + "200_msgs.proto", + "100_fields.proto", + "200_fields.proto", + ], + cmd = "$(execpath :gen_synthetic_protos) $(RULEDIR)", +) + +proto_library( + name = "100_msgs_proto", + srcs = ["100_msgs.proto"], +) + +proto_library( + name = "200_msgs_proto", + srcs = ["200_msgs.proto"], +) + +proto_library( + name = "100_fields_proto", + srcs = ["100_fields.proto"], +) + +proto_library( + name = "200_fields_proto", + srcs = ["200_fields.proto"], +) + +proto_library( + name = "empty_proto", + srcs = ["empty.proto"], +) + +[( +upb_proto_library( + name = k + "_upb_proto", + deps = [":" + k + "_proto"], +), +cc_proto_library( + name = k + "_cc_proto", + deps = [":" + k + "_proto"], +), +tmpl_cc_binary( + name = k + "_upb_binary", + testonly = 1, + gen = ":gen_upb_binary_c", + args = [ + package_name() + "/" + k + ".upb.h", + "upb_benchmark_" + v, + ], + deps = [ + ":" + k + "_upb_proto", + ], +), +tmpl_cc_binary( + name = k + "_protobuf_binary", + testonly = 1, + gen = ":gen_protobuf_binary_cc", + args = [ + package_name() + "/" + k + ".pb.h", + "upb_benchmark::" + v, + ], + deps = [ + ":" + k + "_cc_proto", + ], +), +cc_lite_proto_library( + srcs = [k + ".proto"], + outs = [k + "_lite.proto"], + name = k + "_cc_lite_proto", +), +tmpl_cc_binary( + name = k + "_lite_protobuf_binary", + testonly = 1, + gen = ":gen_protobuf_binary_cc", + args = [ + package_name() + "/" + k + "_lite.pb.h", + "upb_benchmark::" + v, + ], + deps = [ + ":" + k + "_cc_lite_proto", + ], +)) for k, v in SIZE_BENCHMARKS.items()] + +genrule( + testonly = 1, + name = "size_data", + srcs = expand_suffixes( + SIZE_BENCHMARKS.keys(), + suffixes = ["_upb_binary", "_protobuf_binary", "_lite_protobuf_binary"], + ), + outs = ["size_data.txt"], + # We want --format=GNU which counts rodata with data, not text. + cmd = "size $$($$OSTYPE == 'linux-gnu' ? '--format=GNU -d' : '') $(SRCS) > $@", + # "size" sometimes isn't available remotely. + local = 1, +) diff --git a/benchmarks/benchmark.cc b/benchmarks/benchmark.cc index cc510bdd6c..7f4765a88c 100644 --- a/benchmarks/benchmark.cc +++ b/benchmarks/benchmark.cc @@ -115,31 +115,31 @@ static void BM_LoadAdsDescriptor_Proto2(benchmark::State& state) { } BENCHMARK(BM_LoadAdsDescriptor_Proto2); -static void BM_Parse_Upb_FileDesc_WithArena(benchmark::State& state) { - size_t bytes = 0; - for (auto _ : state) { - upb_arena* arena = upb_arena_new(); - upb_benchmark_FileDescriptorProto* set = - upb_benchmark_FileDescriptorProto_parse(descriptor.data, - descriptor.size, arena); - if (!set) { - printf("Failed to parse.\n"); - exit(1); - } - bytes += descriptor.size; - upb_arena_free(arena); - } - state.SetBytesProcessed(state.iterations() * descriptor.size); -} -BENCHMARK(BM_Parse_Upb_FileDesc_WithArena); +enum CopyStrings { + Copy, + Alias, +}; + +enum ArenaMode { + NoArena, + UseArena, + InitBlock, +}; -static void BM_Parse_Upb_FileDesc_WithInitialBlock(benchmark::State& state) { +template +static void BM_Parse_Upb_FileDesc(benchmark::State& state) { size_t bytes = 0; for (auto _ : state) { - upb_arena* arena = upb_arena_init(buf, sizeof(buf), NULL); + upb_arena *arena; + if (AMode == InitBlock) { + arena = upb_arena_init(buf, sizeof(buf), NULL); + } else { + arena = upb_arena_new(); + } upb_benchmark_FileDescriptorProto* set = - upb_benchmark_FileDescriptorProto_parse(descriptor.data, - descriptor.size, arena); + upb_benchmark_FileDescriptorProto_parse_ex( + descriptor.data, descriptor.size, arena, + Copy == Alias ? UPB_DECODE_ALIAS : 0); if (!set) { printf("Failed to parse.\n"); exit(1); @@ -149,10 +149,16 @@ static void BM_Parse_Upb_FileDesc_WithInitialBlock(benchmark::State& state) { } state.SetBytesProcessed(state.iterations() * descriptor.size); } -BENCHMARK(BM_Parse_Upb_FileDesc_WithInitialBlock); +BENCHMARK_TEMPLATE(BM_Parse_Upb_FileDesc, UseArena, Copy); +BENCHMARK_TEMPLATE(BM_Parse_Upb_FileDesc, UseArena, Alias); +BENCHMARK_TEMPLATE(BM_Parse_Upb_FileDesc, InitBlock, Copy); +BENCHMARK_TEMPLATE(BM_Parse_Upb_FileDesc, InitBlock, Alias); -template -struct NoArena { +template +struct Proto2Factory; + +template +struct Proto2Factory { public: P* GetProto() { return &proto_; } @@ -161,7 +167,7 @@ struct NoArena { }; template -struct WithArena { +struct Proto2Factory { public: P* GetProto() { return protobuf::Arena::CreateMessage

(&arena_); } @@ -170,9 +176,9 @@ struct WithArena { }; template -struct WithInitialBlock { +struct Proto2Factory { public: - WithInitialBlock() : arena_(GetOptions()) {} + Proto2Factory() : arena_(GetOptions()) {} P* GetProto() { return protobuf::Arena::CreateMessage

(&arena_); } private: @@ -189,17 +195,15 @@ struct WithInitialBlock { using FileDesc = ::upb_benchmark::FileDescriptorProto; using FileDescSV = ::upb_benchmark::sv::FileDescriptorProto; -const protobuf::MessageLite::ParseFlags kMergePartial = - protobuf::MessageLite::ParseFlags::kMergePartial; -const protobuf::MessageLite::ParseFlags kAlias = - protobuf::MessageLite::ParseFlags::kMergePartialWithAliasing; - -template class Factory, - protobuf::MessageLite::ParseFlags kParseFlags = kMergePartial> +template void BM_Parse_Proto2(benchmark::State& state) { size_t bytes = 0; + constexpr protobuf::MessageLite::ParseFlags kParseFlags = + kCopy == Copy + ? protobuf::MessageLite::ParseFlags::kMergePartial + : protobuf::MessageLite::ParseFlags::kMergePartialWithAliasing; for (auto _ : state) { - Factory

proto_factory; + Proto2Factory proto_factory; auto proto = proto_factory.GetProto(); protobuf::StringPiece input(descriptor.data,descriptor.size); bool ok = proto->template ParseFrom(input); @@ -211,15 +215,10 @@ void BM_Parse_Proto2(benchmark::State& state) { } state.SetBytesProcessed(state.iterations() * descriptor.size); } -BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDesc, NoArena); -BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDesc, WithArena); -BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDesc, WithInitialBlock); -//BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDescSV, NoArena); -//BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDescSV, WithArena); -BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDescSV, WithInitialBlock); -//BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDescSV, NoArena, kAlias); -//BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDescSV, WithArena, kAlias); -BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDescSV, WithInitialBlock, kAlias); +BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDesc, NoArena, Copy); +BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDesc, UseArena, Copy); +BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDesc, InitBlock, Copy); +BENCHMARK_TEMPLATE(BM_Parse_Proto2, FileDescSV, InitBlock, Alias); static void BM_SerializeDescriptor_Proto2(benchmark::State& state) { size_t bytes = 0; diff --git a/benchmarks/build_defs.bzl b/benchmarks/build_defs.bzl new file mode 100644 index 0000000000..533c84454c --- /dev/null +++ b/benchmarks/build_defs.bzl @@ -0,0 +1,63 @@ + +# copybara:insert_for_google3_begin +# load("//tools/build_defs/proto/cpp:cc_proto_library.bzl", _cc_proto_library="cc_proto_library") +# copybara:insert_end + +# copybara:strip_for_google3_begin +_cc_proto_library = native.cc_proto_library +# copybara:strip_end + +def proto_library(**kwargs): + native.proto_library( + # copybara:insert_for_google3_begin + # cc_api_version = 2, + # copybara:insert_end + **kwargs, + ) + +def tmpl_cc_binary(name, gen, args, replacements = [], **kwargs): + srcs = [name + ".cc"] + native.genrule( + name = name + "_gen_srcs", + tools = [gen], + outs = srcs, + cmd = "$(location " + gen + ") " + " ".join(args) + " > $@", + ) + + native.cc_binary( + # copybara:insert_for_google3_begin + # malloc="//base:system_malloc", + # features = ["-static_linking_mode"], + # copybara:insert_end + name = name, + srcs = srcs, + **kwargs, + ) + +def cc_lite_proto_library(name, srcs, outs): + if len(srcs) != 1: + fail("Currently srcs must have exactly 1 element") + + native.genrule( + name = name + "_gen_proto", + srcs = srcs, + outs = outs, + cmd = "cp $< $@ && chmod a+w $@ && echo 'option optimize_for = LITE_RUNTIME;' >> $@", + ) + + proto_library( + name = name + "_proto", + srcs = outs, + ) + + _cc_proto_library( + name = name, + deps = [":" + name + "_proto"], + ) + +def expand_suffixes(vals, suffixes): + ret = [] + for val in vals: + for suffix in suffixes: + ret.append(val + suffix) + return ret diff --git a/benchmarks/compare.py b/benchmarks/compare.py index ad8a1901e8..9824ca0100 100755 --- a/benchmarks/compare.py +++ b/benchmarks/compare.py @@ -27,13 +27,16 @@ def GitWorktree(commit): def Run(cmd): subprocess.check_call(cmd, shell=True) -def Benchmark(outbase, bench_cpu=True, runs=12): +def Benchmark(outbase, bench_cpu=True, runs=12, new=False): tmpfile = "/tmp/bench-output.json" Run("rm -rf {}".format(tmpfile)) Run("CC=clang bazel test ...") if bench_cpu: - Run("CC=clang bazel build -c opt --copt=-march=native benchmarks:benchmark") + if new: + Run("CC=clang bazel build -c opt --copt=-march=native --//:fasttable_enabled=true benchmarks:benchmark") + else: + Run("CC=clang bazel build -c opt --copt=-march=native benchmarks:benchmark") Run("./bazel-bin/benchmarks/benchmark --benchmark_out_format=json --benchmark_out={} --benchmark_repetitions={}".format(tmpfile, runs)) with open(tmpfile) as f: @@ -48,7 +51,10 @@ def Benchmark(outbase, bench_cpu=True, runs=12): values = (name, run["iterations"], run["cpu_time"]) print("{} {} {} ns/op".format(*values), file=f) - Run("CC=clang bazel build -c opt --copt=-g tests:conformance_upb") + if new: + Run("CC=clang bazel build -c opt --copt=-g --//:fasttable_enabled=true tests:conformance_upb") + else: + Run("CC=clang bazel build -c opt --copt=-g tests:conformance_upb") Run("cp -f bazel-bin/tests/conformance_upb {}.bin".format(outbase)) @@ -63,7 +69,7 @@ if len(sys.argv) > 1: pass # Benchmark our current directory first, since it's more likely to be broken. -Benchmark("/tmp/new", bench_cpu) +Benchmark("/tmp/new", bench_cpu, new=True) # Benchmark the baseline. with GitWorktree(baseline): diff --git a/benchmarks/descriptor.proto b/benchmarks/descriptor.proto index a95371d4da..b69b27f89e 100644 --- a/benchmarks/descriptor.proto +++ b/benchmarks/descriptor.proto @@ -48,10 +48,6 @@ option csharp_namespace = "Google.Protobuf.Reflection"; option objc_class_prefix = "GPB"; option cc_enable_arenas = true; -// descriptor.proto must be optimized for speed because reflection-based -// algorithms don't work during bootstrapping. -option optimize_for = SPEED; - // The protocol compiler can output a FileDescriptorSet containing the .proto // files it parses. message FileDescriptorSet { diff --git a/benchmarks/descriptor_sv.proto b/benchmarks/descriptor_sv.proto index c595a68649..8ca0888da7 100644 --- a/benchmarks/descriptor_sv.proto +++ b/benchmarks/descriptor_sv.proto @@ -47,10 +47,6 @@ option csharp_namespace = "Google.Protobuf.Reflection"; option objc_class_prefix = "GPB"; option cc_enable_arenas = true; -// descriptor.proto must be optimized for speed because reflection-based -// algorithms don't work during bootstrapping. -option optimize_for = SPEED; - // The protocol compiler can output a FileDescriptorSet containing the .proto // files it parses. message FileDescriptorSet { diff --git a/benchmarks/empty.proto b/benchmarks/empty.proto new file mode 100644 index 0000000000..bcccaf9abe --- /dev/null +++ b/benchmarks/empty.proto @@ -0,0 +1,6 @@ + +syntax = "proto3"; + +package upb_benchmark; + +message Empty {} diff --git a/benchmarks/gen_protobuf_binary_cc.py b/benchmarks/gen_protobuf_binary_cc.py new file mode 100644 index 0000000000..787e391547 --- /dev/null +++ b/benchmarks/gen_protobuf_binary_cc.py @@ -0,0 +1,38 @@ + +import sys +import re + +include = sys.argv[1] +msg_basename = sys.argv[2] +count = 1 + +m = re.search(r'(.*\D)(\d+)$', sys.argv[2]) +if m: + msg_basename = m.group(1) + count = int(m.group(2)) + +print(''' +#include "{include}" + +char buf[1]; + +int main() {{ +'''.format(include=include)) + +def RefMessage(name): + print(''' + {{ + {name} proto; + proto.ParseFromArray(buf, 0); + proto.SerializePartialToArray(&buf[0], 0); + }} + '''.format(name=name)) + +RefMessage(msg_basename) + +for i in range(2, count + 1): + RefMessage(msg_basename + str(i)) + +print(''' + return 0; +}''') diff --git a/benchmarks/gen_synthetic_protos.py b/benchmarks/gen_synthetic_protos.py new file mode 100644 index 0000000000..a95deff080 --- /dev/null +++ b/benchmarks/gen_synthetic_protos.py @@ -0,0 +1,92 @@ + +import sys +import random + +base = sys.argv[1] + +field_freqs = [ + (('bool', 'optional'), 8.321), + (('bool', 'repeated'), 0.033), + (('bytes', 'optional'), 0.809), + (('bytes', 'repeated'), 0.065), + (('double', 'optional'), 2.845), + (('double', 'repeated'), 0.143), + (('fixed32', 'optional'), 0.084), + (('fixed32', 'repeated'), 0.012), + (('fixed64', 'optional'), 0.204), + (('fixed64', 'repeated'), 0.027), + (('float', 'optional'), 2.355), + (('float', 'repeated'), 0.132), + (('int32', 'optional'), 6.717), + (('int32', 'repeated'), 0.366), + (('int64', 'optional'), 9.678), + (('int64', 'repeated'), 0.425), + (('sfixed32', 'optional'), 0.018), + (('sfixed32', 'repeated'), 0.005), + (('sfixed64', 'optional'), 0.022), + (('sfixed64', 'repeated'), 0.005), + (('sint32', 'optional'), 0.026), + (('sint32', 'repeated'), 0.009), + (('sint64', 'optional'), 0.018), + (('sint64', 'repeated'), 0.006), + (('string', 'optional'), 25.461), + (('string', 'repeated'), 2.606), + (('Enum', 'optional'), 6.16), + (('Enum', 'repeated'), 0.576), + (('Message', 'optional'), 22.472), + (('Message', 'repeated'), 7.766), + (('uint32', 'optional'), 1.289), + (('uint32', 'repeated'), 0.051), + (('uint64', 'optional'), 1.044), + (('uint64', 'repeated'), 0.079), +] + +population = [item[0] for item in field_freqs] +weights = [item[1] for item in field_freqs] + +def choices(k): + if sys.version_info >= (3, 6): + return random.choices(population=population, weights=weights, k=k) + else: + print("WARNING: old Python version, field types are not properly weighted!") + return [random.choice(population) for _ in range(k)] + +with open(base + "/100_msgs.proto", "w") as f: + f.write('syntax = "proto3";\n') + f.write('package upb_benchmark;\n') + f.write('message Message {}\n') + for i in range(2, 101): + f.write('message Message{i} {{}}\n'.format(i=i)) + +with open(base + "/200_msgs.proto", "w") as f: + f.write('syntax = "proto3";\n') + f.write('package upb_benchmark;\n') + f.write('message Message {}\n') + for i in range(2, 501): + f.write('message Message{i} {{}}\n'.format(i=i)) + +with open(base + "/100_fields.proto", "w") as f: + f.write('syntax = "proto2";\n') + f.write('package upb_benchmark;\n') + f.write('enum Enum { ZERO = 0; }\n') + f.write('message Message {\n') + i = 1 + random.seed(a=0, version=2) + for field in choices(100): + field_type, label = field + f.write(' {label} {field_type} field{i} = {i};\n'.format(i=i, label=label, field_type=field_type)) + i += 1 + f.write('}\n') + +with open(base + "/200_fields.proto", "w") as f: + f.write('syntax = "proto2";\n') + f.write('package upb_benchmark;\n') + f.write('enum Enum { ZERO = 0; }\n') + f.write('message Message {\n') + i = 1 + random.seed(a=0, version=2) + for field in choices(200): + field_type, label = field + f.write(' {label} {field_type} field{i} = {i};\n'.format(i=i, label=label,field_type=field_type)) + i += 1 + f.write('}\n') diff --git a/benchmarks/gen_upb_binary_c.py b/benchmarks/gen_upb_binary_c.py new file mode 100644 index 0000000000..4df8fd7327 --- /dev/null +++ b/benchmarks/gen_upb_binary_c.py @@ -0,0 +1,39 @@ + +import sys +import re + +include = sys.argv[1] +msg_basename = sys.argv[2] +count = 1 + +m = re.search(r'(.*\D)(\d+)$', sys.argv[2]) +if m: + msg_basename = m.group(1) + count = int(m.group(2)) + +print(''' +#include "{include}" + +char buf[1]; + +int main() {{ + upb_arena *arena = upb_arena_new(); + size_t size; +'''.format(include=include)) + +def RefMessage(name): + print(''' + {{ + {name} *proto = {name}_parse(buf, 1, arena); + {name}_serialize(proto, arena, &size); + }} + '''.format(name=name)) + +RefMessage(msg_basename) + +for i in range(2, count + 1): + RefMessage(msg_basename + str(i)) + +print(''' + return 0; +}''') diff --git a/cmake/google/protobuf/descriptor.upb.h b/cmake/google/protobuf/descriptor.upb.h index ccb902ba12..a8ed71a688 100644 --- a/cmake/google/protobuf/descriptor.upb.h +++ b/cmake/google/protobuf/descriptor.upb.h @@ -164,6 +164,12 @@ UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_ google_protobuf_FileDescriptorSet *ret = google_protobuf_FileDescriptorSet_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_FileDescriptorSet *ret = google_protobuf_FileDescriptorSet_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_FileDescriptorSet_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -195,6 +201,12 @@ UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorPr google_protobuf_FileDescriptorProto *ret = google_protobuf_FileDescriptorProto_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_FileDescriptorProto *ret = google_protobuf_FileDescriptorProto_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_FileDescriptorProto_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -352,6 +364,12 @@ UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_pars google_protobuf_DescriptorProto *ret = google_protobuf_DescriptorProto_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_DescriptorProto *ret = google_protobuf_DescriptorProto_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_DescriptorProto_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -505,6 +523,12 @@ UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_Descr 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; } +UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + 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; +} 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); } @@ -548,6 +572,12 @@ UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_Descri 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; } +UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + 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; +} 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); } @@ -576,6 +606,12 @@ UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRange google_protobuf_ExtensionRangeOptions *ret = google_protobuf_ExtensionRangeOptions_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_ExtensionRangeOptions *ret = google_protobuf_ExtensionRangeOptions_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_ExtensionRangeOptions_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -607,6 +643,12 @@ UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptor google_protobuf_FieldDescriptorProto *ret = google_protobuf_FieldDescriptorProto_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_FieldDescriptorProto *ret = google_protobuf_FieldDescriptorProto_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_FieldDescriptorProto_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -698,6 +740,12 @@ UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptor google_protobuf_OneofDescriptorProto *ret = google_protobuf_OneofDescriptorProto_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_OneofDescriptorProto *ret = google_protobuf_OneofDescriptorProto_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_OneofDescriptorProto_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -735,6 +783,12 @@ UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorPr google_protobuf_EnumDescriptorProto *ret = google_protobuf_EnumDescriptorProto_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_EnumDescriptorProto *ret = google_protobuf_EnumDescriptorProto_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumDescriptorProto_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -813,6 +867,12 @@ UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobu 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; } +UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + 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; +} 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); } @@ -841,6 +901,12 @@ UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDe google_protobuf_EnumValueDescriptorProto *ret = google_protobuf_EnumValueDescriptorProto_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_EnumValueDescriptorProto *ret = google_protobuf_EnumValueDescriptorProto_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumValueDescriptorProto_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -884,6 +950,12 @@ UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescri google_protobuf_ServiceDescriptorProto *ret = google_protobuf_ServiceDescriptorProto_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_ServiceDescriptorProto *ret = google_protobuf_ServiceDescriptorProto_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_ServiceDescriptorProto_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -936,6 +1008,12 @@ UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescript google_protobuf_MethodDescriptorProto *ret = google_protobuf_MethodDescriptorProto_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_MethodDescriptorProto *ret = google_protobuf_MethodDescriptorProto_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_MethodDescriptorProto_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -997,6 +1075,12 @@ UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parse(const google_protobuf_FileOptions *ret = google_protobuf_FileOptions_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_FileOptions *ret = google_protobuf_FileOptions_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_FileOptions_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -1148,6 +1232,12 @@ UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parse( google_protobuf_MessageOptions *ret = google_protobuf_MessageOptions_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_MessageOptions *ret = google_protobuf_MessageOptions_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_MessageOptions_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -1203,6 +1293,12 @@ UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parse(cons google_protobuf_FieldOptions *ret = google_protobuf_FieldOptions_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_FieldOptions *ret = google_protobuf_FieldOptions_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_FieldOptions_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -1270,6 +1366,12 @@ UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parse(cons google_protobuf_OneofOptions *ret = google_protobuf_OneofOptions_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_OneofOptions *ret = google_protobuf_OneofOptions_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_OneofOptions_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -1301,6 +1403,12 @@ UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parse(const google_protobuf_EnumOptions *ret = google_protobuf_EnumOptions_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_EnumOptions *ret = google_protobuf_EnumOptions_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumOptions_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -1344,6 +1452,12 @@ UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_pa google_protobuf_EnumValueOptions *ret = google_protobuf_EnumValueOptions_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_EnumValueOptions *ret = google_protobuf_EnumValueOptions_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_EnumValueOptions_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -1381,6 +1495,12 @@ UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parse( google_protobuf_ServiceOptions *ret = google_protobuf_ServiceOptions_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_ServiceOptions *ret = google_protobuf_ServiceOptions_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_ServiceOptions_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -1418,6 +1538,12 @@ UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parse(co google_protobuf_MethodOptions *ret = google_protobuf_MethodOptions_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_MethodOptions *ret = google_protobuf_MethodOptions_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_MethodOptions_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -1461,6 +1587,12 @@ UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOpt google_protobuf_UninterpretedOption *ret = google_protobuf_UninterpretedOption_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_UninterpretedOption *ret = google_protobuf_UninterpretedOption_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_UninterpretedOption_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -1528,6 +1660,12 @@ UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_Uninter 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; } +UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + 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; +} 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); } @@ -1556,6 +1694,12 @@ UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parse( google_protobuf_SourceCodeInfo *ret = google_protobuf_SourceCodeInfo_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_SourceCodeInfo *ret = google_protobuf_SourceCodeInfo_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_SourceCodeInfo_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -1587,6 +1731,12 @@ UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeIn 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; } +UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + 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; +} 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); } @@ -1648,6 +1798,12 @@ UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_ google_protobuf_GeneratedCodeInfo *ret = google_protobuf_GeneratedCodeInfo_new(arena); return (ret && upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, arena)) ? ret : NULL; } +UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + google_protobuf_GeneratedCodeInfo *ret = google_protobuf_GeneratedCodeInfo_new(arena); + return (ret && _upb_decode(buf, size, ret, &google_protobuf_GeneratedCodeInfo_msginit, arena, options)) + ? ret : NULL; +} 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); } @@ -1679,6 +1835,12 @@ UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_Generat 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; } +UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + 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; +} 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/kokoro/ubuntu/presubmit.cfg b/kokoro/ubuntu/presubmit.cfg index fa97583b34..0a7f20c6d1 100644 --- a/kokoro/ubuntu/presubmit.cfg +++ b/kokoro/ubuntu/presubmit.cfg @@ -1,2 +1,2 @@ build_file: "upb/kokoro/ubuntu/build.sh" -timeout_mins: 15 +timeout_mins: 30 diff --git a/upb/decode.c b/upb/decode.c index 0037768b4c..588b35171e 100644 --- a/upb/decode.c +++ b/upb/decode.c @@ -644,10 +644,11 @@ const char *fastdecode_generic(struct upb_decstate *d, const char *ptr, return decode_msg(d, ptr, msg, decode_totablep(table)); } -bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l, - upb_arena *arena) { +bool _upb_decode(const char *buf, size_t size, void *msg, + const upb_msglayout *l, upb_arena *arena, int options) { bool ok; upb_decstate state; + unsigned depth = (unsigned)options >> 16; if (size == 0) { return true; @@ -661,12 +662,12 @@ bool upb_decode(const char *buf, size_t size, void *msg, const upb_msglayout *l, } else { state.end = buf + size - 16; state.limit = 16; - state.alias = true; + state.alias = options & UPB_DECODE_ALIAS; } state.limit_ptr = state.end; state.unknown_msg = NULL; - state.depth = 64; + state.depth = depth ? depth : 64; state.end_group = DECODE_NOGROUP; state.arena.head = arena->head; state.arena.last_size = arena->last_size; diff --git a/upb/decode.h b/upb/decode.h index 9de8638de5..00419ab373 100644 --- a/upb/decode.h +++ b/upb/decode.h @@ -7,15 +7,32 @@ #include "upb/msg.h" +/* Must be last. */ +#include "upb/port_def.inc" + #ifdef __cplusplus extern "C" { #endif +enum { + UPB_DECODE_ALIAS = 1, +}; + +#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); + +UPB_INLINE bool upb_decode(const char *buf, size_t size, upb_msg *msg, - const upb_msglayout *l, upb_arena *arena); + const upb_msglayout *l, upb_arena *arena) { + return _upb_decode(buf, size, msg, l, arena, 0); +} #ifdef __cplusplus } /* extern "C" */ #endif +#include "upb/port_undef.inc" + #endif /* UPB_DECODE_H_ */ diff --git a/upb/decode_fast.c b/upb/decode_fast.c index f58f70ebec..f628e6dbd4 100644 --- a/upb/decode_fast.c +++ b/upb/decode_fast.c @@ -763,7 +763,7 @@ again: } else if (UPB_LIKELY(size <= 64)) { if (UPB_UNLIKELY(common_has < 64)) goto longstr; fastdecode_docopy(d, ptr, size, 64, buf, dst); - } else if (UPB_LIKELY(size <= 128)) { + } else if (UPB_LIKELY(size < 128)) { if (UPB_UNLIKELY(common_has < 128)) goto longstr; fastdecode_docopy(d, ptr, size, 128, buf, dst); } else { diff --git a/upb/def.c b/upb/def.c index 70cd050476..5ac9ceddc9 100644 --- a/upb/def.c +++ b/upb/def.c @@ -2139,8 +2139,8 @@ bool _upb_symtab_loaddefinit(upb_symtab *s, const upb_def_init *init) { if (!_upb_symtab_loaddefinit(s, *deps)) goto err; } - file = google_protobuf_FileDescriptorProto_parse( - init->descriptor.data, init->descriptor.size, arena); + file = google_protobuf_FileDescriptorProto_parse_ex( + init->descriptor.data, init->descriptor.size, arena, UPB_DECODE_ALIAS); s->bytes_loaded += init->descriptor.size; if (!file) { diff --git a/upb/upb.c b/upb/upb.c index 8e6ad77142..a12656973d 100644 --- a/upb/upb.c +++ b/upb/upb.c @@ -178,15 +178,14 @@ upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc) { } a = UPB_PTR_AT(mem, n - sizeof(*a), upb_arena); - n -= sizeof(*a); a->head.alloc.func = &upb_arena_doalloc; a->block_alloc = alloc; a->parent = a; a->refcount = 1; - a->last_size = 128; + a->last_size = UPB_MAX(128, n); a->head.ptr = mem; - a->head.end = UPB_PTR_AT(mem, n, char); + a->head.end = UPB_PTR_AT(mem, n - sizeof(*a), char); a->freelist = NULL; a->cleanups = NULL; diff --git a/upbc/generator.cc b/upbc/generator.cc index f4d1bb9b8d..4f9db9ad91 100644 --- a/upbc/generator.cc +++ b/upbc/generator.cc @@ -348,6 +348,12 @@ void GenerateMessageInHeader(const protobuf::Descriptor* message, Output& output " $0 *ret = $0_new(arena);\n" " return (ret && upb_decode(buf, size, ret, &$1, arena)) ? ret : NULL;\n" "}\n" + "UPB_INLINE $0 *$0_parse_ex(const char *buf, size_t size,\n" + " upb_arena *arena, int options) {\n" + " $0 *ret = $0_new(arena);\n" + " return (ret && _upb_decode(buf, size, ret, &$1, arena, options))\n" + " ? ret : NULL;\n" + "}\n" "UPB_INLINE char *$0_serialize(const $0 *msg, upb_arena *arena, size_t " "*len) {\n" " return upb_encode(msg, &$1, arena, len);\n"