diff --git a/.gitmodules b/.gitmodules
index 2b085e15059..f3653b475c4 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -51,9 +51,6 @@
[submodule "third_party/protoc-gen-validate"]
path = third_party/protoc-gen-validate
url = https://github.com/envoyproxy/protoc-gen-validate.git
-[submodule "third_party/upb"]
- path = third_party/upb
- url = https://github.com/protocolbuffers/upb.git
[submodule "third_party/udpa"]
path = third_party/udpa
url = https://github.com/cncf/udpa.git
diff --git a/third_party/upb b/third_party/upb
deleted file mode 160000
index 931bbecbd32..00000000000
--- a/third_party/upb
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 931bbecbd3230ae7f22efa5d203639facc47f719
diff --git a/third_party/upb/.bazelci/presubmit.yml b/third_party/upb/.bazelci/presubmit.yml
new file mode 100644
index 00000000000..38ca79304f9
--- /dev/null
+++ b/third_party/upb/.bazelci/presubmit.yml
@@ -0,0 +1,10 @@
+---
+tasks:
+ ubuntu:
+ platform: ubuntu1604
+ test_targets:
+ - //...
+ macos:
+ platform: macos
+ test_targets:
+ - //...
diff --git a/third_party/upb/.gitignore b/third_party/upb/.gitignore
new file mode 100644
index 00000000000..c9bd5becf81
--- /dev/null
+++ b/third_party/upb/.gitignore
@@ -0,0 +1,4 @@
+*.s??
+obj/
+lib/
+bazel-*
diff --git a/third_party/upb/.gitmodules b/third_party/upb/.gitmodules
new file mode 100644
index 00000000000..8b52c1d2165
--- /dev/null
+++ b/third_party/upb/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "third_party/protobuf"]
+ path = third_party/protobuf
+ url = https://github.com/google/protobuf.git
diff --git a/third_party/upb/BUILD b/third_party/upb/BUILD
new file mode 100644
index 00000000000..ad85b202a9a
--- /dev/null
+++ b/third_party/upb/BUILD
@@ -0,0 +1,727 @@
+load(
+ "//bazel:build_defs.bzl",
+ "generated_file_staleness_test",
+ "licenses", # copybara:strip_for_google3
+ "lua_binary",
+ "lua_cclibrary",
+ "lua_library",
+ "lua_test",
+ "make_shell_script",
+ "upb_amalgamation",
+)
+load(
+ "//bazel:upb_proto_library.bzl",
+ "upb_proto_library",
+ "upb_proto_reflection_library",
+)
+
+licenses(["notice"]) # BSD (Google-authored w/ possible external contributions)
+
+exports_files([
+ "LICENSE",
+ "build_defs",
+])
+
+CPPOPTS = [
+ # copybara:strip_for_google3_begin
+ "-Werror",
+ "-Wno-long-long",
+ # copybara:strip_end
+]
+
+COPTS = CPPOPTS + [
+ # copybara:strip_for_google3_begin
+ "-pedantic",
+ "-Wstrict-prototypes",
+ # copybara:strip_end
+]
+
+config_setting(
+ name = "darwin",
+ values = {"cpu": "darwin"},
+ visibility = ["//visibility:public"],
+)
+
+config_setting(
+ name = "windows",
+ constraint_values = ["@bazel_tools//platforms:windows"],
+)
+
+config_setting(
+ name = "fuzz",
+ values = {"define": "fuzz=true"},
+)
+
+# Public C/C++ libraries #######################################################
+
+cc_library(
+ name = "upb",
+ srcs = [
+ "upb/decode.c",
+ "upb/encode.c",
+ "upb/generated_util.h",
+ "upb/msg.c",
+ "upb/msg.h",
+ "upb/port.c",
+ "upb/port_def.inc",
+ "upb/port_undef.inc",
+ "upb/table.c",
+ "upb/table.int.h",
+ "upb/upb.c",
+ ],
+ hdrs = [
+ "upb/decode.h",
+ "upb/encode.h",
+ "upb/upb.h",
+ ],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": COPTS
+ }),
+ visibility = ["//visibility:public"],
+)
+
+# Common support routines used by generated code. This library has no
+# implementation, but depends on :upb and exposes a few more hdrs.
+#
+# This is public only because we have no way of visibility-limiting it to
+# upb_proto_library() only. This interface is not stable and by using it you
+# give up any backward compatibility guarantees.
+cc_library(
+ name = "generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
+ hdrs = [
+ "upb/generated_util.h",
+ "upb/msg.h",
+ ],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": COPTS
+ }),
+ textual_hdrs = [
+ "upb/port_def.inc",
+ "upb/port_undef.inc",
+ ],
+ visibility = ["//visibility:public"],
+ deps = [":upb"],
+)
+
+upb_proto_library(
+ name = "descriptor_upbproto",
+ visibility = ["//visibility:public"],
+ deps = ["@com_google_protobuf//:descriptor_proto"],
+)
+
+cc_library(
+ name = "reflection",
+ srcs = [
+ "upb/def.c",
+ "upb/msgfactory.c",
+ ],
+ hdrs = [
+ "upb/def.h",
+ "upb/msgfactory.h",
+ ],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": COPTS
+ }),
+ visibility = ["//visibility:public"],
+ deps = [
+ ":descriptor_upbproto",
+ ":table",
+ ":upb",
+ ],
+)
+
+# Internal C/C++ libraries #####################################################
+
+cc_library(
+ name = "table",
+ hdrs = ["upb/table.int.h"],
+ deps = [":upb"],
+)
+
+# Legacy C/C++ Libraries (not recommended for new code) ########################
+
+cc_library(
+ name = "legacy_msg_reflection",
+ srcs = [
+ "upb/legacy_msg_reflection.c",
+ ],
+ hdrs = ["upb/legacy_msg_reflection.h"],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": COPTS
+ }),
+ deps = [
+ ":table",
+ ":upb",
+ ],
+)
+
+cc_library(
+ name = "handlers",
+ srcs = [
+ "upb/handlers.c",
+ "upb/handlers-inl.h",
+ "upb/sink.c",
+ ],
+ hdrs = [
+ "upb/handlers.h",
+ "upb/sink.h",
+ ],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": COPTS
+ }),
+ deps = [
+ ":reflection",
+ ":table",
+ ":upb",
+ ],
+)
+
+cc_library(
+ name = "upb_pb",
+ srcs = [
+ "upb/pb/compile_decoder.c",
+ "upb/pb/decoder.c",
+ "upb/pb/decoder.int.h",
+ "upb/pb/encoder.c",
+ "upb/pb/textprinter.c",
+ "upb/pb/varint.c",
+ "upb/pb/varint.int.h",
+ ],
+ hdrs = [
+ "upb/pb/decoder.h",
+ "upb/pb/encoder.h",
+ "upb/pb/textprinter.h",
+ ],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": COPTS
+ }),
+ deps = [
+ ":descriptor_upbproto",
+ ":handlers",
+ ":reflection",
+ ":table",
+ ":upb",
+ ],
+)
+
+# copybara:strip_for_google3_begin
+cc_library(
+ name = "upb_json",
+ srcs = [
+ "upb/json/parser.c",
+ "upb/json/printer.c",
+ ],
+ hdrs = [
+ "upb/json/parser.h",
+ "upb/json/printer.h",
+ ],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": COPTS
+ }),
+ deps = [
+ ":upb",
+ ":upb_pb",
+ ],
+)
+# copybara:strip_end
+
+cc_library(
+ name = "upb_cc_bindings",
+ hdrs = [
+ "upb/bindings/stdc++/string.h",
+ ],
+ deps = [
+ ":descriptor_upbproto",
+ ":handlers",
+ ":upb",
+ ],
+)
+
+# upb compiler #################################################################
+
+cc_library(
+ name = "upbc_generator",
+ srcs = [
+ "upbc/generator.cc",
+ "upbc/message_layout.cc",
+ "upbc/message_layout.h",
+ ],
+ hdrs = ["upbc/generator.h"],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": CPPOPTS
+ }),
+ deps = [
+ "@absl//absl/base:core_headers",
+ "@absl//absl/container:flat_hash_map",
+ "@absl//absl/strings",
+ "@com_google_protobuf//:protobuf",
+ "@com_google_protobuf//:protoc_lib",
+ ],
+)
+
+cc_binary(
+ name = "protoc-gen-upb",
+ srcs = ["upbc/main.cc"],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": CPPOPTS
+ }),
+ visibility = ["//visibility:public"],
+ deps = [
+ ":upbc_generator",
+ "@com_google_protobuf//:protoc_lib",
+ ],
+)
+
+# We strip the tests and remaining rules from google3 until the upb_proto_library()
+# and upb_proto_reflection_library() rules are fixed.
+
+# C/C++ tests ##################################################################
+
+cc_binary(
+ name = "benchmark",
+ testonly = 1,
+ srcs = ["tests/benchmark.cc"],
+ deps = [
+ ":descriptor_upbproto",
+ ":descriptor_upbreflection",
+ "@com_github_google_benchmark//:benchmark_main",
+ ],
+)
+
+cc_library(
+ name = "upb_test",
+ testonly = 1,
+ srcs = [
+ "tests/testmain.cc",
+ ],
+ hdrs = [
+ "tests/test_util.h",
+ "tests/upb_test.h",
+ ],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": CPPOPTS
+ }),
+ deps = [
+ ":handlers",
+ ":upb",
+ ],
+)
+
+cc_test(
+ name = "test_varint",
+ srcs = [
+ "tests/pb/test_varint.c",
+ "upb/pb/varint.int.h",
+ ],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": COPTS
+ }),
+ deps = [
+ ":upb",
+ ":upb_pb",
+ ":upb_test",
+ ],
+)
+
+proto_library(
+ name = "test_decoder_proto",
+ srcs = [
+ "tests/pb/test_decoder.proto",
+ ],
+)
+
+upb_proto_reflection_library(
+ name = "test_decoder_upbproto",
+ deps = [":test_decoder_proto"],
+)
+
+cc_test(
+ name = "test_decoder",
+ srcs = [
+ "tests/pb/test_decoder.cc",
+ "upb/pb/varint.int.h",
+ ],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": CPPOPTS
+ }),
+ deps = [
+ ":handlers",
+ ":test_decoder_upbproto",
+ ":upb",
+ ":upb_pb",
+ ":upb_test",
+ ],
+)
+
+proto_library(
+ name = "test_cpp_proto",
+ srcs = [
+ "tests/test_cpp.proto",
+ ],
+)
+
+upb_proto_reflection_library(
+ name = "test_cpp_upbproto",
+ deps = ["test_cpp_proto"],
+)
+
+cc_test(
+ name = "test_cpp",
+ srcs = ["tests/test_cpp.cc"],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": CPPOPTS
+ }),
+ deps = [
+ ":handlers",
+ ":reflection",
+ ":test_cpp_upbproto",
+ ":upb",
+ ":upb_pb",
+ ":upb_test",
+ ],
+)
+
+cc_test(
+ name = "test_table",
+ srcs = ["tests/test_table.cc"],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": CPPOPTS
+ }),
+ deps = [
+ ":table",
+ ":upb",
+ ":upb_test",
+ ],
+)
+
+# OSS-Fuzz test
+cc_binary(
+ name = "file_descriptor_parsenew_fuzzer",
+ testonly = 1,
+ srcs = ["tests/file_descriptor_parsenew_fuzzer.cc"],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": CPPOPTS
+ }) + select({
+ "//conditions:default": [],
+ ":fuzz": ["-fsanitize=fuzzer,address"],
+ }),
+ defines = select({
+ "//conditions:default": [],
+ ":fuzz": ["HAVE_FUZZER"],
+ }),
+ deps = [
+ ":descriptor_upbproto",
+ ":upb",
+ ],
+)
+
+# copybara:strip_for_google3_begin
+upb_proto_reflection_library(
+ name = "descriptor_upbreflection",
+ deps = ["@com_google_protobuf//:descriptor_proto"],
+)
+
+cc_test(
+ name = "test_encoder",
+ srcs = ["tests/pb/test_encoder.cc"],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": CPPOPTS
+ }),
+ deps = [
+ ":descriptor_upbproto",
+ ":descriptor_upbreflection",
+ ":upb",
+ ":upb_cc_bindings",
+ ":upb_pb",
+ ":upb_test",
+ ],
+)
+
+proto_library(
+ name = "test_json_enum_from_separate",
+ srcs = ["tests/json/enum_from_separate_file.proto"],
+ deps = [":test_json_proto"],
+)
+
+proto_library(
+ name = "test_json_proto",
+ srcs = ["tests/json/test.proto"],
+)
+
+upb_proto_reflection_library(
+ name = "test_json_upbprotoreflection",
+ deps = ["test_json_proto"],
+)
+
+upb_proto_library(
+ name = "test_json_enum_from_separate_upbproto",
+ deps = [":test_json_enum_from_separate"],
+)
+
+upb_proto_library(
+ name = "test_json_upbproto",
+ deps = [":test_json_proto"],
+)
+
+cc_test(
+ name = "test_json",
+ srcs = [
+ "tests/json/test_json.cc",
+ ],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": CPPOPTS
+ }),
+ deps = [
+ ":test_json_upbproto",
+ ":test_json_upbprotoreflection",
+ ":upb_json",
+ ":upb_test",
+ ],
+)
+# copybara:strip_end
+
+upb_proto_library(
+ name = "conformance_proto_upb",
+ testonly = 1,
+ deps = ["@com_google_protobuf//:conformance_proto"],
+)
+
+upb_proto_library(
+ name = "test_messages_proto3_proto_upb",
+ testonly = 1,
+ deps = ["@com_google_protobuf//:test_messages_proto3_proto"],
+)
+
+cc_binary(
+ name = "conformance_upb",
+ testonly = 1,
+ srcs = [
+ "tests/conformance_upb.c",
+ ],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": COPTS
+ }) + ["-Ibazel-out/k8-fastbuild/bin"],
+ deps = [
+ ":conformance_proto_upb",
+ ":test_messages_proto3_proto_upb",
+ ":upb",
+ ],
+)
+
+make_shell_script(
+ name = "gen_test_conformance_upb",
+ out = "test_conformance_upb.sh",
+ contents = "external/com_google_protobuf/conformance_test_runner ./conformance_upb",
+)
+
+sh_test(
+ name = "test_conformance_upb",
+ srcs = ["test_conformance_upb.sh"],
+ data = [
+ "tests/conformance_upb_failures.txt",
+ ":conformance_upb",
+ "@com_google_protobuf//:conformance_test_runner",
+ ],
+)
+
+# copybara:strip_for_google3_begin
+
+# Amalgamation #################################################################
+
+py_binary(
+ name = "amalgamate",
+ srcs = ["tools/amalgamate.py"],
+)
+
+upb_amalgamation(
+ name = "gen_amalgamation",
+ outs = [
+ "upb.c",
+ "upb.h",
+ ],
+ amalgamator = ":amalgamate",
+ libs = [
+ ":upb",
+ ":descriptor_upbproto",
+ ":reflection",
+ ":handlers",
+ ":upb_pb",
+ ":upb_json",
+ ],
+)
+
+cc_library(
+ name = "amalgamation",
+ srcs = ["upb.c"],
+ hdrs = ["upb.h"],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": COPTS
+ }),
+)
+
+# Lua libraries. ###############################################################
+
+lua_cclibrary(
+ name = "lua/upb_c",
+ srcs = [
+ "upb/bindings/lua/def.c",
+ "upb/bindings/lua/msg.c",
+ "upb/bindings/lua/upb.c",
+ ],
+ hdrs = [
+ "upb/bindings/lua/upb.h",
+ ],
+ deps = [
+ "legacy_msg_reflection",
+ "upb",
+ "upb_pb",
+ ],
+)
+
+lua_library(
+ name = "lua/upb",
+ srcs = ["upb/bindings/lua/upb.lua"],
+ luadeps = ["lua/upb_c"],
+ strip_prefix = "upb/bindings/lua",
+)
+
+lua_cclibrary(
+ name = "lua/upb/pb_c",
+ srcs = ["upb/bindings/lua/upb/pb.c"],
+ luadeps = ["lua/upb_c"],
+ deps = ["upb_pb"],
+)
+
+lua_library(
+ name = "lua/upb/pb",
+ srcs = ["upb/bindings/lua/upb/pb.lua"],
+ luadeps = [
+ "lua/upb",
+ "lua/upb/pb_c",
+ ],
+ strip_prefix = "upb/bindings/lua",
+)
+
+# Lua tests. ###################################################################
+
+lua_test(
+ name = "lua/test_upb",
+ luadeps = ["lua/upb"],
+ luamain = "tests/bindings/lua/test_upb.lua",
+)
+
+lua_test(
+ name = "lua/test_upb_pb",
+ luadeps = ["lua/upb/pb"],
+ luamain = "tests/bindings/lua/test_upb.pb.lua",
+)
+
+# Test the CMake build #########################################################
+
+filegroup(
+ name = "cmake_files",
+ srcs = glob([
+ "CMakeLists.txt",
+ "generated_for_cmake/**/*",
+ "google/**/*",
+ "upbc/**/*",
+ "upb/**/*",
+ "tests/**/*",
+ ]),
+)
+
+make_shell_script(
+ name = "gen_run_cmake_build",
+ out = "run_cmake_build.sh",
+ contents = "find . && mkdir build && cd build && cmake .. && make -j8 && make test",
+)
+
+sh_test(
+ name = "cmake_build",
+ srcs = ["run_cmake_build.sh"],
+ data = [":cmake_files"],
+)
+
+# Generated files ##############################################################
+
+exports_files(["tools/staleness_test.py"])
+
+py_library(
+ name = "staleness_test_lib",
+ testonly = 1,
+ srcs = ["tools/staleness_test_lib.py"],
+)
+
+py_binary(
+ name = "make_cmakelists",
+ srcs = ["tools/make_cmakelists.py"],
+)
+
+genrule(
+ name = "gen_cmakelists",
+ srcs = [
+ "BUILD",
+ "WORKSPACE",
+ ":cmake_files",
+ ],
+ outs = ["generated-in/CMakeLists.txt"],
+ cmd = "$(location :make_cmakelists) $@",
+ tools = [":make_cmakelists"],
+)
+
+genrule(
+ name = "generate_json_ragel",
+ srcs = ["upb/json/parser.rl"],
+ outs = ["upb/json/parser.c"],
+ cmd = "$(location @ragel//:ragelc) -C -o upb/json/parser.c $< && mv upb/json/parser.c $@",
+ tools = ["@ragel//:ragelc"],
+)
+
+genrule(
+ name = "copy_json_ragel",
+ srcs = ["upb/json/parser.c"],
+ outs = ["generated-in/generated_for_cmake/upb/json/parser.c"],
+ cmd = "cp $< $@",
+)
+
+genrule(
+ name = "copy_protos",
+ srcs = [":descriptor_upbproto"],
+ outs = [
+ "generated-in/generated_for_cmake/google/protobuf/descriptor.upb.c",
+ "generated-in/generated_for_cmake/google/protobuf/descriptor.upb.h",
+ ],
+ cmd = "cp $(SRCS) $(@D)/generated-in/generated_for_cmake/google/protobuf",
+)
+
+generated_file_staleness_test(
+ name = "test_generated_files",
+ outs = [
+ "CMakeLists.txt",
+ "generated_for_cmake/google/protobuf/descriptor.upb.c",
+ "generated_for_cmake/google/protobuf/descriptor.upb.h",
+ "generated_for_cmake/upb/json/parser.c",
+ ],
+ generated_pattern = "generated-in/%s",
+)
+
+# copybara:strip_end
diff --git a/third_party/upb/CMakeLists.txt b/third_party/upb/CMakeLists.txt
new file mode 100644
index 00000000000..836c5ff1fe5
--- /dev/null
+++ b/third_party/upb/CMakeLists.txt
@@ -0,0 +1,147 @@
+# This file was generated from BUILD using tools/make_cmakelists.py.
+
+cmake_minimum_required(VERSION 3.1)
+
+if(${CMAKE_VERSION} VERSION_LESS 3.12)
+ cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
+else()
+ cmake_policy(VERSION 3.12)
+endif()
+
+cmake_minimum_required (VERSION 3.0)
+cmake_policy(SET CMP0048 NEW)
+
+project(upb)
+
+
+# Prevent CMake from setting -rdynamic on Linux (!!).
+SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
+SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
+
+# Set default build type.
+if(NOT CMAKE_BUILD_TYPE)
+ message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.")
+ set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING
+ "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."
+ FORCE)
+endif()
+
+# When using Ninja, compiler output won't be colorized without this.
+include(CheckCXXCompilerFlag)
+CHECK_CXX_COMPILER_FLAG(-fdiagnostics-color=always SUPPORTS_COLOR_ALWAYS)
+if(SUPPORTS_COLOR_ALWAYS)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
+endif()
+
+# Implement ASAN/UBSAN options
+if(UPB_ENABLE_ASAN)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
+endif()
+
+if(UPB_ENABLE_UBSAN)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
+endif()
+
+include_directories(.)
+include_directories(generated_for_cmake)
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+if(APPLE)
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -undefined dynamic_lookup -flat_namespace")
+elseif(UNIX)
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id")
+endif()
+
+enable_testing()
+
+add_library(upb
+ upb/decode.c
+ upb/encode.c
+ upb/generated_util.h
+ upb/msg.c
+ upb/msg.h
+ upb/port.c
+ upb/port_def.inc
+ upb/port_undef.inc
+ upb/table.c
+ upb/table.int.h
+ upb/upb.c
+ upb/decode.h
+ upb/encode.h
+ upb/upb.h)
+add_library(generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me INTERFACE)
+target_link_libraries(generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me INTERFACE
+ upb)
+add_library(reflection
+ upb/def.c
+ upb/msgfactory.c
+ upb/def.h
+ upb/msgfactory.h)
+target_link_libraries(reflection
+ descriptor_upbproto
+ table
+ upb)
+add_library(table INTERFACE)
+target_link_libraries(table INTERFACE
+ upb)
+add_library(legacy_msg_reflection
+ upb/legacy_msg_reflection.c
+ upb/legacy_msg_reflection.h)
+target_link_libraries(legacy_msg_reflection
+ table
+ upb)
+add_library(handlers
+ upb/handlers.c
+ upb/handlers-inl.h
+ upb/sink.c
+ upb/handlers.h
+ upb/sink.h)
+target_link_libraries(handlers
+ reflection
+ table
+ upb)
+add_library(upb_pb
+ upb/pb/compile_decoder.c
+ upb/pb/decoder.c
+ upb/pb/decoder.int.h
+ upb/pb/encoder.c
+ upb/pb/textprinter.c
+ upb/pb/varint.c
+ upb/pb/varint.int.h
+ upb/pb/decoder.h
+ upb/pb/encoder.h
+ upb/pb/textprinter.h)
+target_link_libraries(upb_pb
+ descriptor_upbproto
+ handlers
+ reflection
+ table
+ upb)
+add_library(upb_json
+ generated_for_cmake/upb/json/parser.c
+ upb/json/printer.c
+ upb/json/parser.h
+ upb/json/printer.h)
+target_link_libraries(upb_json
+ upb
+ upb_pb)
+add_library(upb_cc_bindings INTERFACE)
+target_link_libraries(upb_cc_bindings INTERFACE
+ descriptor_upbproto
+ handlers
+ upb)
+add_library(upb_test
+ tests/testmain.cc
+ tests/test_util.h
+ tests/upb_test.h)
+target_link_libraries(upb_test
+ handlers
+ upb)
+
+
diff --git a/third_party/upb/CONTRIBUTING.md b/third_party/upb/CONTRIBUTING.md
new file mode 100644
index 00000000000..2f866b4e291
--- /dev/null
+++ b/third_party/upb/CONTRIBUTING.md
@@ -0,0 +1,7 @@
+## Signing the CLA
+
+Please sign the [Google Contributor License Agreement
+(CLA)](https://cla.developers.google.com/)
+before sending pull requests. For any code changes to be
+accepted, the CLA must be signed. It's a quick process, I
+promise!
diff --git a/third_party/upb/DESIGN.md b/third_party/upb/DESIGN.md
new file mode 100644
index 00000000000..a7a8a284516
--- /dev/null
+++ b/third_party/upb/DESIGN.md
@@ -0,0 +1,72 @@
+
+μpb Design
+----------
+
+μpb has the following design goals:
+
+- C89 compatible.
+- small code size (both for the core library and generated messages).
+- fast performance (hundreds of MB/s).
+- idiomatic for C programs.
+- easy to wrap in high-level languages (Python, Ruby, Lua, etc) with
+ good performance and all standard protobuf features.
+- hands-off about memory management, allowing for easy integration
+ with existing VMs and/or garbage collectors.
+- offers binary ABI compatibility between apps, generated messages, and
+ the core library (doesn't require re-generating messages or recompiling
+ your application when the core library changes).
+- provides all features that users expect from a protobuf library
+ (generated messages in C, reflection, text format, etc.).
+- layered, so the core is small and doesn't require descriptors.
+- tidy about symbol references, so that any messages or features that
+ aren't used by a C program can have their code GC'd by the linker.
+- possible to use protobuf binary format without leaking message/field
+ names into the binary.
+
+μpb accomplishes these goals by keeping a very small core that does not contain
+descriptors. We need some way of knowing what fields are in each message and
+where they live, but instead of descriptors, we keep a small/lightweight summary
+of the .proto file. We call this a `upb_msglayout`. It contains the bare
+minimum of what we need to know to parse and serialize protobuf binary format
+into our internal representation for messages, `upb_msg`.
+
+The core then contains functions to parse/serialize a message, given a `upb_msg*`
+and a `const upb_msglayout*`.
+
+This approach is similar to [nanopb](https://github.com/nanopb/nanopb) which
+also compiles message definitions to a compact, internal representation without
+names. However nanopb does not aim to be a fully-featured library, and has no
+support for text format, JSON, or descriptors. μpb is unique in that it has a
+small core similar to nanopb (though not quite as small), but also offers a
+full-featured protobuf library for applications that want reflection, text
+format, JSON format, etc.
+
+Without descriptors, the core doesn't have access to field names, so it cannot
+parse/serialize to protobuf text format or JSON. Instead this functionality
+lives in separate modules that depend on the module implementing descriptors.
+With the descriptor module we can parse/serialize binary descriptors and
+validate that they follow all the rules of protobuf schemas.
+
+To provide binary compatibility, we version the structs that generated messages
+use to create a `upb_msglayout*`. The current initializers are
+`upb_msglayout_msginit_v1`, `upb_msglayout_fieldinit_v1`, etc. Then
+`upb_msglayout*` uses these as its internal representation. If upb changes its
+internal representation for a `upb_msglayout*`, it will also include code to
+convert the old representation to the new representation. This will use some
+more memory/CPU at runtime to convert between the two, but apps that statically
+link μpb will never need to worry about this.
+
+TODO
+----
+
+1. revise our generated code until it is in a state where we feel comfortable
+ committing to API/ABI stability for it. In particular there is an open
+ question of whether non-ABI-compatible field accesses should have a
+ fastpath different from the ABI-compatible field access.
+1. Add missing features (maps, extensions, unknown fields).
+1. Flesh out C++ wrappers.
+1. *(lower-priority)*: revise all of the existing encoders/decoders and
+ handlers. We probably will want to keep handlers, since they let us decouple
+ encoders/decoders from `upb_msg`, but we need to simplify all of that a LOT.
+ Likely we will want to make handlers only per-message instead of per-field,
+ except for variable-length fields.
diff --git a/third_party/upb/LICENSE b/third_party/upb/LICENSE
new file mode 100644
index 00000000000..da939845db6
--- /dev/null
+++ b/third_party/upb/LICENSE
@@ -0,0 +1,26 @@
+
+Copyright (c) 2009-2011, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Google Inc. nor the names of any other
+ contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL GOOGLE INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/third_party/upb/README.md b/third_party/upb/README.md
new file mode 100644
index 00000000000..a08aa0e9092
--- /dev/null
+++ b/third_party/upb/README.md
@@ -0,0 +1,134 @@
+
+# μpb - a small protobuf implementation in C
+
+|Platform|Build Status|
+|--------|------------|
+|macOS|[](https://fusion.corp.google.com/projectanalysis/summary/KOKORO/prod%3Aupb%2Fmacos%2Fcontinuous)|
+|ubuntu|[](https://fusion.corp.google.com/projectanalysis/summary/KOKORO/prod%3Aupb%2Fubuntu%2Fcontinuous)|
+
+μpb (often written 'upb') is a small protobuf implementation written in C.
+
+upb generates a C API for creating, parsing, and serializing messages
+as declared in `.proto` files. upb is heavily arena-based: all
+messages always live in an arena (note: the arena can live in stack or
+static memory if desired). Here is a simple example:
+
+```c
+#include "conformance/conformance.upb.h"
+
+void foo(const char* data, size_t size) {
+ upb_arena *arena;
+
+ /* Generated message type. */
+ conformance_ConformanceRequest *request;
+ conformance_ConformanceResponse *response;
+
+ arena = upb_arena_new();
+ request = conformance_ConformanceRequest_parse(data, size, arena);
+ response = conformance_ConformanceResponse_new(arena);
+
+ switch (conformance_ConformanceRequest_payload_case(request)) {
+ case conformance_ConformanceRequest_payload_protobuf_payload: {
+ upb_strview payload = conformance_ConformanceRequest_protobuf_payload(request);
+ // ...
+ break;
+ }
+
+ case conformance_ConformanceRequest_payload_NOT_SET:
+ fprintf(stderr, "conformance_upb: Request didn't have payload.\n");
+ break;
+
+ default: {
+ static const char msg[] = "Unsupported input format.";
+ conformance_ConformanceResponse_set_skipped(
+ response, upb_strview_make(msg, sizeof(msg)));
+ break;
+ }
+ }
+
+ /* Frees all messages on the arena. */
+ upb_arena_free(arena);
+}
+```
+
+API and ABI are both subject to change! Please do not distribute
+as a shared library for this reason (for now at least).
+
+## Using upb in your project
+
+Currently only Bazel is supported (CMake support is partial and incomplete
+but full CMake support is an eventual goal).
+
+To use upb in your Bazel project, first add upb to your `WORKSPACE` file,
+either as a `git_repository()` or as a `new_local_repository()` with a
+Git Submodule. (For an example, see `examples/bazel/ in this repo).
+
+```python
+# Add this to your WORKSPACE file.
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
+
+git_repository(
+ name = "upb",
+ remote = "https://github.com/protocolbuffers/upb.git",
+ commit = "d16bf99ac4658793748cda3251226059892b3b7b",
+)
+
+load("@upb//bazel:workspace_deps.bzl", "upb_deps")
+
+upb_deps()
+```
+
+Then in your BUILD file you can add `upb_proto_library()` rules that
+generate code for a corresponding `proto_library()` rule. For
+example:
+
+```python
+# Add this to your BUILD file.
+load("@upb//bazel:upb_proto_library.bzl", "upb_proto_library")
+
+proto_library(
+ name = "foo_proto",
+ srcs = ["foo.proto"],
+)
+
+upb_proto_library(
+ name = "foo_upbproto",
+ deps = [":foo_proto"],
+)
+
+cc_binary(
+ name = "test_binary",
+ srcs = ["test_binary.c"],
+ deps = [":foo_upbproto"],
+)
+```
+
+Then in your `.c` file you can #include the generated header:
+
+```c
+#include "foo.upb.h"
+
+/* Insert code that uses generated types. */
+```
+
+## Old "handlers" interfaces
+
+This library contains several semi-deprecated interfaces (see BUILD
+file for more info about which interfaces are deprecated). These
+deprecated interfaces are still used in some significant projects,
+such as the Ruby and PHP C bindings for protobuf in the [main protobuf
+repo](https://github.com/protocolbuffers/protobuf). The goal is to
+migrate the Ruby/PHP bindings to use the newer, simpler interfaces
+instead. Please do not use the old interfaces in new code.
+
+## Lua bindings
+
+This repo has some Lua bindings for the core library. These are
+experimental and very incomplete. These are currently included in
+order to validate that the C API is suitable for wrapping. As the
+project matures these Lua bindings may become publicly available.
+
+## Contact
+
+Author: Josh Haberman ([jhaberman@gmail.com](mailto:jhaberman@gmail.com),
+[haberman@google.com](mailto:haberman@google.com))
diff --git a/third_party/upb/WORKSPACE b/third_party/upb/WORKSPACE
new file mode 100644
index 00000000000..c1c8c3be9b7
--- /dev/null
+++ b/third_party/upb/WORKSPACE
@@ -0,0 +1,39 @@
+workspace(name = "upb")
+
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("//bazel:workspace_deps.bzl", "upb_deps")
+
+upb_deps()
+
+http_archive(
+ name = "lua",
+ build_file = "//bazel:lua.BUILD",
+ sha256 = "b9e2e4aad6789b3b63a056d442f7b39f0ecfca3ae0f1fc0ae4e9614401b69f4b",
+ strip_prefix = "lua-5.2.4",
+ urls = [
+ "https://mirror.bazel.build/www.lua.org/ftp/lua-5.2.4.tar.gz",
+ "https://www.lua.org/ftp/lua-5.2.4.tar.gz",
+ ],
+)
+
+http_archive(
+ name = "ragel",
+ build_file = "//bazel:ragel.BUILD",
+ sha256 = "5f156edb65d20b856d638dd9ee2dfb43285914d9aa2b6ec779dac0270cd56c3f",
+ strip_prefix = "ragel-6.10",
+ urls = ["http://www.colm.net/files/ragel/ragel-6.10.tar.gz"],
+)
+
+http_archive(
+ name = "com_google_googletest",
+ urls = ["https://github.com/google/googletest/archive/b6cd405286ed8635ece71c72f118e659f4ade3fb.zip"], # 2019-01-07
+ strip_prefix = "googletest-b6cd405286ed8635ece71c72f118e659f4ade3fb",
+ sha256 = "ff7a82736e158c077e76188232eac77913a15dac0b22508c390ab3f88e6d6d86",
+)
+
+http_archive(
+ name = "com_github_google_benchmark",
+ urls = ["https://github.com/google/benchmark/archive/16703ff83c1ae6d53e5155df3bb3ab0bc96083be.zip"],
+ strip_prefix = "benchmark-16703ff83c1ae6d53e5155df3bb3ab0bc96083be",
+ sha256 = "59f918c8ccd4d74b6ac43484467b500f1d64b40cc1010daa055375b322a43ba3",
+)
diff --git a/third_party/upb/bazel/BUILD b/third_party/upb/bazel/BUILD
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/third_party/upb/bazel/build_defs.bzl b/third_party/upb/bazel/build_defs.bzl
new file mode 100644
index 00000000000..08bb44ee3f7
--- /dev/null
+++ b/third_party/upb/bazel/build_defs.bzl
@@ -0,0 +1,221 @@
+"""Internal rules for building upb."""
+
+load(":upb_proto_library.bzl", "GeneratedSrcsInfo")
+
+def _librule(name):
+ return name + "_lib"
+
+def _get_real_short_path(file):
+ # For some reason, files from other archives have short paths that look like:
+ # ../com_google_protobuf/google/protobuf/descriptor.proto
+ short_path = file.short_path
+ if short_path.startswith("../"):
+ second_slash = short_path.index("/", 3)
+ short_path = short_path[second_slash + 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 lua_cclibrary(name, srcs, hdrs = [], deps = [], luadeps = []):
+ lib_rule = name + "_lib"
+ so_rule = "lib" + name + ".so"
+ so_file = _remove_prefix(name, "lua/") + ".so"
+
+ native.cc_library(
+ name = _librule(name),
+ hdrs = hdrs,
+ srcs = srcs,
+ deps = deps + [_librule(dep) for dep in luadeps] + ["@lua//:liblua_headers"],
+ )
+
+ native.cc_binary(
+ name = so_rule,
+ linkshared = True,
+ deps = [_librule(name)],
+ linkopts = select({
+ ":darwin": [
+ "-undefined dynamic_lookup",
+ ],
+ "//conditions:default": [],
+ }),
+ )
+
+ native.genrule(
+ name = name + "_copy",
+ srcs = [":" + so_rule],
+ outs = [so_file],
+ cmd = "cp $< $@",
+ )
+
+ native.filegroup(
+ name = name,
+ data = [so_file],
+ )
+
+def _remove_prefix(str, prefix):
+ if not str.startswith(prefix):
+ fail("%s doesn't start with %s" % (str, prefix))
+ return str[len(prefix):]
+
+def _remove_suffix(str, suffix):
+ if not str.endswith(suffix):
+ fail("%s doesn't end with %s" % (str, suffix))
+ return str[:-len(suffix)]
+
+def lua_library(name, srcs, strip_prefix, luadeps = []):
+ outs = [_remove_prefix(src, strip_prefix + "/") for src in srcs]
+ native.genrule(
+ name = name + "_copy",
+ srcs = srcs,
+ outs = outs,
+ cmd = "cp $(SRCS) $(@D)",
+ )
+
+ native.filegroup(
+ name = name,
+ data = outs + luadeps,
+ )
+
+def make_shell_script(name, contents, out):
+ contents = contents.replace("$", "$$")
+ native.genrule(
+ name = "gen_" + name,
+ outs = [out],
+ cmd = "(cat <<'HEREDOC'\n%s\nHEREDOC\n) > $@" % contents,
+ )
+
+def _lua_binary_or_test(name, luamain, luadeps, rule):
+ script = name + ".sh"
+
+ make_shell_script(
+ name = "gen_" + name,
+ out = script,
+ contents = """
+BASE=$(dirname $(rlocation upb/upb_c.so))
+export LUA_CPATH="$BASE/?.so"
+export LUA_PATH="$BASE/?.lua"
+$(rlocation lua/lua) $(rlocation upb/tools/upbc.lua) "$@"
+""",
+ )
+
+ rule(
+ name = name,
+ srcs = [script],
+ data = ["@lua//:lua", luamain] + luadeps,
+ )
+
+def lua_binary(name, luamain, luadeps = []):
+ _lua_binary_or_test(name, luamain, luadeps, native.sh_binary)
+
+def lua_test(name, luamain, luadeps = []):
+ _lua_binary_or_test(name, luamain, luadeps, native.sh_test)
+
+def generated_file_staleness_test(name, outs, generated_pattern):
+ """Tests that checked-in file(s) match the contents of generated file(s).
+
+ The resulting test will verify that all output files exist and have the
+ correct contents. If the test fails, it can be invoked with --fix to
+ bring the checked-in files up to date.
+
+ Args:
+ name: Name of the rule.
+ outs: the checked-in files that are copied from generated files.
+ generated_pattern: the pattern for transforming each "out" file into a
+ generated file. For example, if generated_pattern="generated/%s" then
+ a file foo.txt will look for generated file generated/foo.txt.
+ """
+
+ script_name = name + ".py"
+ script_src = "//:tools/staleness_test.py"
+
+ # Filter out non-existing rules so Blaze doesn't error out before we even
+ # run the test.
+ existing_outs = native.glob(include = outs)
+
+ # The file list contains a few extra bits of information at the end.
+ # These get unpacked by the Config class in staleness_test_lib.py.
+ file_list = outs + [generated_pattern, native.package_name() or ".", name]
+
+ native.genrule(
+ name = name + "_makescript",
+ outs = [script_name],
+ srcs = [script_src],
+ testonly = 1,
+ cmd = "cat $(location " + script_src + ") > $@; " +
+ "sed -i.bak -e 's|INSERT_FILE_LIST_HERE|" + "\\\n ".join(file_list) + "|' $@",
+ )
+
+ native.py_test(
+ name = name,
+ srcs = [script_name],
+ data = existing_outs + [generated_pattern % file for file in outs],
+ deps = [
+ "//:staleness_test_lib",
+ ],
+ )
+
+# upb_amalgamation() rule, with file_list aspect.
+
+SrcList = provider(
+ fields = {
+ "srcs": "list of srcs",
+ },
+)
+
+def _file_list_aspect_impl(target, ctx):
+ if GeneratedSrcsInfo in target:
+ srcs = target[GeneratedSrcsInfo]
+ return [SrcList(srcs = srcs.srcs + srcs.hdrs)]
+
+ srcs = []
+ for src in ctx.rule.attr.srcs:
+ srcs += src.files.to_list()
+ for hdr in ctx.rule.attr.hdrs:
+ srcs += hdr.files.to_list()
+ for hdr in ctx.rule.attr.textual_hdrs:
+ srcs += hdr.files.to_list()
+ return [SrcList(srcs = srcs)]
+
+_file_list_aspect = aspect(
+ implementation = _file_list_aspect_impl,
+)
+
+def _upb_amalgamation(ctx):
+ inputs = []
+ for lib in ctx.attr.libs:
+ inputs += lib[SrcList].srcs
+ srcs = [src for src in inputs if src.path.endswith("c")]
+ ctx.actions.run(
+ inputs = inputs,
+ outputs = ctx.outputs.outs,
+ arguments = [ctx.bin_dir.path + "/"] + [f.path for f in srcs] + ["-I" + root for root in _get_real_roots(inputs)],
+ progress_message = "Making amalgamation",
+ executable = ctx.executable.amalgamator,
+ )
+ return []
+
+upb_amalgamation = rule(
+ attrs = {
+ "amalgamator": attr.label(
+ executable = True,
+ cfg = "host",
+ ),
+ "libs": attr.label_list(aspects = [_file_list_aspect]),
+ "outs": attr.output_list(),
+ },
+ implementation = _upb_amalgamation,
+)
+
+def licenses(*args):
+ # No-op (for Google-internal usage).
+ pass
diff --git a/third_party/upb/bazel/lua.BUILD b/third_party/upb/bazel/lua.BUILD
new file mode 100644
index 00000000000..7be0b594e56
--- /dev/null
+++ b/third_party/upb/bazel/lua.BUILD
@@ -0,0 +1,102 @@
+package(
+ default_visibility = ["//visibility:public"],
+)
+
+cc_library(
+ name = "liblua_headers",
+ defines = ["LUA_USE_LINUX"],
+ hdrs = [
+ "src/lauxlib.h",
+ "src/lua.h",
+ "src/lua.hpp",
+ "src/luaconf.h",
+ "src/lualib.h",
+ ],
+ includes = ["src"],
+)
+
+cc_library(
+ name = "liblua",
+ srcs = [
+ "src/lapi.c",
+ "src/lapi.h",
+ "src/lauxlib.c",
+ "src/lauxlib.h",
+ "src/lbaselib.c",
+ "src/lbitlib.c",
+ "src/lcode.c",
+ "src/lcode.h",
+ "src/lcorolib.c",
+ "src/lctype.c",
+ "src/lctype.h",
+ "src/ldblib.c",
+ "src/ldebug.c",
+ "src/ldebug.h",
+ "src/ldo.c",
+ "src/ldo.h",
+ "src/ldump.c",
+ "src/lfunc.c",
+ "src/lfunc.h",
+ "src/lgc.c",
+ "src/lgc.h",
+ "src/linit.c",
+ "src/liolib.c",
+ "src/llex.c",
+ "src/llex.h",
+ "src/llimits.h",
+ "src/lmathlib.c",
+ "src/lmem.c",
+ "src/lmem.h",
+ "src/loadlib.c",
+ "src/lobject.c",
+ "src/lobject.h",
+ "src/lopcodes.c",
+ "src/lopcodes.h",
+ "src/loslib.c",
+ "src/lparser.c",
+ "src/lparser.h",
+ "src/lstate.c",
+ "src/lstate.h",
+ "src/lstring.c",
+ "src/lstring.h",
+ "src/lstrlib.c",
+ "src/ltable.c",
+ "src/ltable.h",
+ "src/ltablib.c",
+ "src/ltm.c",
+ "src/ltm.h",
+ "src/lundump.c",
+ "src/lundump.h",
+ "src/lvm.c",
+ "src/lvm.h",
+ "src/lzio.c",
+ "src/lzio.h",
+ ],
+ defines = ["LUA_USE_LINUX"],
+ hdrs = [
+ "src/lauxlib.h",
+ "src/lua.h",
+ "src/lua.hpp",
+ "src/luaconf.h",
+ "src/lualib.h",
+ ],
+ includes = ["src"],
+ linkopts = [
+ "-lm",
+ "-ldl",
+ ],
+)
+
+cc_binary(
+ name = "lua",
+ srcs = [
+ "src/lua.c",
+ ],
+ deps = [
+ ":liblua",
+ ],
+ linkopts = [
+ "-lreadline",
+ "-rdynamic",
+ ],
+)
diff --git a/third_party/upb/bazel/ragel.BUILD b/third_party/upb/bazel/ragel.BUILD
new file mode 100644
index 00000000000..5e3b24913df
--- /dev/null
+++ b/third_party/upb/bazel/ragel.BUILD
@@ -0,0 +1,193 @@
+
+package(
+ default_visibility = ["//visibility:public"],
+)
+
+cc_binary(
+ name = "ragelc",
+ srcs = [
+ "ragel/rubycodegen.cpp",
+ "ragel/goipgoto.h",
+ "ragel/cdtable.h",
+ "ragel/rubycodegen.h",
+ "ragel/gotable.h",
+ "ragel/gocodegen.cpp",
+ "ragel/rubyfflat.cpp",
+ "ragel/common.cpp",
+ "ragel/gofflat.cpp",
+ "ragel/cdtable.cpp",
+ "ragel/cdsplit.cpp",
+ "ragel/rlparse.cpp",
+ "ragel/csfgoto.cpp",
+ "ragel/javacodegen.cpp",
+ "ragel/gocodegen.h",
+ "ragel/mlgoto.cpp",
+ "ragel/fsmgraph.cpp",
+ "ragel/version.h",
+ "ragel/mlfflat.h",
+ "ragel/fsmgraph.h",
+ "ragel/fsmbase.cpp",
+ "ragel/fsmstate.cpp",
+ "ragel/gotablish.cpp",
+ "ragel/rubyflat.cpp",
+ "ragel/cdfgoto.h",
+ "ragel/cscodegen.h",
+ "ragel/mlflat.cpp",
+ "ragel/rubyflat.h",
+ "ragel/goftable.h",
+ "ragel/rbxgoto.cpp",
+ "ragel/csfflat.cpp",
+ "ragel/gofgoto.cpp",
+ "ragel/gofgoto.h",
+ "ragel/ragel.h",
+ "ragel/goftable.cpp",
+ "ragel/cdcodegen.cpp",
+ "ragel/rlparse.h",
+ "ragel/cdsplit.h",
+ "ragel/xmlcodegen.cpp",
+ "ragel/goipgoto.cpp",
+ "ragel/dotcodegen.h",
+ "ragel/gogoto.cpp",
+ "ragel/csflat.h",
+ "ragel/csfflat.h",
+ #"ragel/config.h.in",
+ "ragel/csipgoto.cpp",
+ "ragel/mltable.cpp",
+ "ragel/mlflat.h",
+ "ragel/csftable.cpp",
+ "ragel/cdgoto.h",
+ "ragel/goflat.cpp",
+ "ragel/rubyfflat.h",
+ "ragel/mlftable.h",
+ "ragel/rubyftable.h",
+ "ragel/fsmap.cpp",
+ "ragel/redfsm.cpp",
+ "ragel/goflat.h",
+ "ragel/parsetree.cpp",
+ "ragel/fsmmin.cpp",
+ "ragel/dotcodegen.cpp",
+ "ragel/redfsm.h",
+ "ragel/mlcodegen.cpp",
+ "ragel/cdfgoto.cpp",
+ "ragel/cssplit.cpp",
+ "ragel/cstable.cpp",
+ "ragel/javacodegen.h",
+ "ragel/parsedata.cpp",
+ "ragel/buffer.h",
+ "ragel/gogoto.h",
+ "ragel/csgoto.h",
+ "ragel/pcheck.h",
+ "ragel/rubyftable.cpp",
+ "ragel/csfgoto.h",
+ "ragel/common.h",
+ "ragel/cdftable.h",
+ "ragel/mlgoto.h",
+ "ragel/csgoto.cpp",
+ "ragel/cdflat.h",
+ "ragel/cdipgoto.h",
+ "ragel/cstable.h",
+ "ragel/gendata.h",
+ "ragel/cdfflat.cpp",
+ "ragel/gotable.cpp",
+ "ragel/cdcodegen.h",
+ "ragel/gendata.cpp",
+ "ragel/rubytable.h",
+ "ragel/csflat.cpp",
+ "ragel/inputdata.h",
+ "ragel/inputdata.cpp",
+ "ragel/rubytable.cpp",
+ "ragel/fsmattach.cpp",
+ "ragel/csipgoto.h",
+ "ragel/cscodegen.cpp",
+ "ragel/cdfflat.h",
+ "ragel/rbxgoto.h",
+ "ragel/xmlcodegen.h",
+ "ragel/gofflat.h",
+ "ragel/parsedata.h",
+ "ragel/mlfgoto.h",
+ "ragel/cdflat.cpp",
+ "ragel/config.h",
+ "ragel/rlscan.cpp",
+ "ragel/mlcodegen.h",
+ "ragel/mlfflat.cpp",
+ "ragel/mlftable.cpp",
+ "ragel/mltable.h",
+ "ragel/cdipgoto.cpp",
+ "ragel/cdftable.cpp",
+ "ragel/parsetree.h",
+ "ragel/rlscan.h",
+ "ragel/main.cpp",
+ "ragel/cssplit.h",
+ "ragel/mlfgoto.cpp",
+ "ragel/csftable.h",
+ "ragel/gotablish.h",
+ "ragel/cdgoto.cpp",
+ "aapl/avlmelkey.h",
+ "aapl/dlistmel.h",
+ "aapl/avliset.h",
+ "aapl/avlkeyless.h",
+ "aapl/sbstset.h",
+ "aapl/sbsttable.h",
+ "aapl/quicksort.h",
+ "aapl/avlitree.h",
+ "aapl/avlcommon.h",
+ "aapl/bstset.h",
+ "aapl/avlmel.h",
+ "aapl/insertsort.h",
+ "aapl/dlist.h",
+ "aapl/avlmap.h",
+ "aapl/mergesort.h",
+ "aapl/resize.h",
+ "aapl/bstcommon.h",
+ "aapl/bstmap.h",
+ "aapl/compare.h",
+ "aapl/svector.h",
+ "aapl/avlset.h",
+ "aapl/bsttable.h",
+ "aapl/avlikeyless.h",
+ "aapl/bubblesort.h",
+ "aapl/table.h",
+ "aapl/avlbasic.h",
+ "aapl/vector.h",
+ "aapl/avlimap.h",
+ "aapl/dlistval.h",
+ "aapl/dlcommon.h",
+ "aapl/avlibasic.h",
+ "aapl/sbstmap.h",
+ "aapl/avlimel.h",
+ "aapl/avlimelkey.h",
+ "aapl/avltree.h",
+ ],
+ includes = ["ragel", "aapl"],
+)
+
+config_h_contents = """
+#define PACKAGE "ragel"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "ragel"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "ragel 6.10"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "ragel"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "6.10"
+
+/* Version number of package */
+#define VERSION "6.10"
+"""
+
+genrule(
+ name = "gen_config_h",
+ outs = ["ragel/config.h"],
+ cmd = "(cat <<'HEREDOC'\n%s\nHEREDOC\n) > $@" % config_h_contents,
+)
diff --git a/third_party/upb/bazel/repository_defs.bzl b/third_party/upb/bazel/repository_defs.bzl
new file mode 100644
index 00000000000..7b6e78e8b83
--- /dev/null
+++ b/third_party/upb/bazel/repository_defs.bzl
@@ -0,0 +1,15 @@
+# A hacky way to work around the fact that native.bazel_version is only
+# available from WORKSPACE macros, not BUILD macros or rules.
+#
+# Hopefully we can remove this if/when this is fixed:
+# https://github.com/bazelbuild/bazel/issues/8305
+
+def _impl(repository_ctx):
+ s = "bazel_version = \"" + native.bazel_version + "\""
+ repository_ctx.file("bazel_version.bzl", s)
+ repository_ctx.file("BUILD", "")
+
+bazel_version_repository = repository_rule(
+ implementation = _impl,
+ local = True,
+)
diff --git a/third_party/upb/bazel/upb_proto_library.bzl b/third_party/upb/bazel/upb_proto_library.bzl
new file mode 100644
index 00000000000..cc6bcffaede
--- /dev/null
+++ b/third_party/upb/bazel/upb_proto_library.bzl
@@ -0,0 +1,299 @@
+"""Public rules for using upb protos:
+ - upb_proto_library()
+ - upb_proto_reflection_library()
+"""
+
+load("@bazel_skylib//lib:paths.bzl", "paths")
+load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
+
+# copybara:strip_for_google3_begin
+load("@bazel_skylib//lib:versions.bzl", "versions")
+load("@bazel_version//:bazel_version.bzl", "bazel_version")
+# copybara:strip_end
+
+# Generic support code #########################################################
+
+_is_bazel = not hasattr(native, "genmpm")
+
+def _get_real_short_path(file):
+ # For some reason, files from other archives have short paths that look like:
+ # ../com_google_protobuf/google/protobuf/descriptor.proto
+ short_path = file.short_path
+ if short_path.startswith("../"):
+ second_slash = short_path.index("/", 3)
+ short_path = short_path[second_slash + 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)
+ output_filename = paths.replace_extension(real_short_path, extension)
+ ret = ctx.actions.declare_file(output_filename)
+ return ret
+
+def _filter_none(elems):
+ out = []
+ for elem in elems:
+ if elem:
+ out.append(elem)
+ return out
+
+def _cc_library_func(ctx, name, hdrs, srcs, dep_ccinfos):
+ """Like cc_library(), but callable from rules.
+
+ Args:
+ ctx: Rule context.
+ name: Unique name used to generate output files.
+ hdrs: Public headers that can be #included from other rules.
+ srcs: C/C++ source files.
+ dep_ccinfos: CcInfo providers of dependencies we should build/link against.
+
+ Returns:
+ CcInfo provider for this compilation.
+ """
+
+ compilation_contexts = [info.compilation_context for info in dep_ccinfos]
+ linking_contexts = [info.linking_context for info in dep_ccinfos]
+ toolchain = find_cpp_toolchain(ctx)
+ feature_configuration = cc_common.configure_features(
+ ctx = ctx,
+ cc_toolchain = toolchain,
+ requested_features = ctx.features,
+ unsupported_features = ctx.disabled_features,
+ )
+
+ # copybara:strip_for_google3_begin
+ if bazel_version == "0.24.1":
+ # Compatibility code until gRPC is on 0.25.2 or later.
+ compilation_info = cc_common.compile(
+ ctx = ctx,
+ feature_configuration = feature_configuration,
+ cc_toolchain = toolchain,
+ srcs = srcs,
+ hdrs = hdrs,
+ compilation_contexts = compilation_contexts,
+ )
+ linking_info = cc_common.link(
+ ctx = ctx,
+ feature_configuration = feature_configuration,
+ cc_toolchain = toolchain,
+ cc_compilation_outputs = compilation_info.cc_compilation_outputs,
+ linking_contexts = linking_contexts,
+ )
+ return CcInfo(
+ compilation_context = compilation_info.compilation_context,
+ linking_context = linking_info.linking_context,
+ )
+
+ if not versions.is_at_least("0.25.2", bazel_version):
+ fail("upb requires Bazel >=0.25.2 or 0.24.1")
+
+ # copybara:strip_end
+
+ blaze_only_args = {}
+
+ if not _is_bazel:
+ blaze_only_args["grep_includes"] = ctx.file._grep_includes
+
+ (compilation_context, compilation_outputs) = cc_common.compile(
+ actions = ctx.actions,
+ feature_configuration = feature_configuration,
+ cc_toolchain = toolchain,
+ name = name,
+ srcs = srcs,
+ public_hdrs = hdrs,
+ compilation_contexts = compilation_contexts,
+ **blaze_only_args
+ )
+ (linking_context, linking_outputs) = cc_common.create_linking_context_from_compilation_outputs(
+ actions = ctx.actions,
+ name = name,
+ feature_configuration = feature_configuration,
+ cc_toolchain = toolchain,
+ compilation_outputs = compilation_outputs,
+ linking_contexts = linking_contexts,
+ **blaze_only_args
+ )
+
+ return CcInfo(
+ compilation_context = compilation_context,
+ linking_context = linking_context,
+ )
+
+# upb_proto_library / upb_proto_reflection_library shared code #################
+
+GeneratedSrcsInfo = provider(
+ fields = {
+ "srcs": "list of srcs",
+ "hdrs": "list of hdrs",
+ },
+)
+
+_WrappedCcInfo = provider(fields = ["cc_info"])
+_WrappedGeneratedSrcsInfo = provider(fields = ["srcs"])
+
+def _compile_upb_protos(ctx, proto_info, proto_sources, ext):
+ srcs = [_generate_output_file(ctx, name, ext + ".c") for name in proto_sources]
+ hdrs = [_generate_output_file(ctx, name, ext + ".h") for name in proto_sources]
+ transitive_sets = proto_info.transitive_descriptor_sets.to_list()
+ ctx.actions.run(
+ inputs = depset(
+ direct = [proto_info.direct_descriptor_set],
+ transitive = [proto_info.transitive_descriptor_sets],
+ ),
+ tools = [ctx.executable._upbc],
+ outputs = srcs + hdrs,
+ executable = ctx.executable._protoc,
+ arguments = [
+ "--upb_out=" + _get_real_root(srcs[0]),
+ "--plugin=protoc-gen-upb=" + ctx.executable._upbc.path,
+ "--descriptor_set_in=" + ctx.configuration.host_path_separator.join([f.path for f in transitive_sets]),
+ ] +
+ [_get_real_short_path(file) for file in proto_sources],
+ progress_message = "Generating upb protos for :" + ctx.label.name,
+ )
+ return GeneratedSrcsInfo(srcs = srcs, hdrs = hdrs)
+
+def _upb_proto_rule_impl(ctx):
+ if len(ctx.attr.deps) != 1:
+ fail("only one deps dependency allowed.")
+ dep = ctx.attr.deps[0]
+ if _WrappedCcInfo not in dep or _WrappedGeneratedSrcsInfo not in dep:
+ fail("proto_library rule must generate _WrappedCcInfo and " +
+ "_WrappedGeneratedSrcsInfo (aspect should have handled this).")
+ cc_info = dep[_WrappedCcInfo].cc_info
+ srcs = dep[_WrappedGeneratedSrcsInfo].srcs
+ if (type(cc_info.linking_context.libraries_to_link) == "list"):
+ lib = cc_info.linking_context.libraries_to_link[0]
+ else:
+ lib = cc_info.linking_context.libraries_to_link.to_list()[0]
+ files = _filter_none([
+ lib.static_library,
+ lib.pic_static_library,
+ lib.dynamic_library,
+ ])
+ return [
+ DefaultInfo(files = depset(files + srcs.hdrs + srcs.srcs)),
+ srcs,
+ cc_info,
+ ]
+
+def _upb_proto_aspect_impl(target, ctx):
+ proto_info = target[ProtoInfo]
+ files = _compile_upb_protos(ctx, proto_info, proto_info.direct_sources, ctx.attr._ext)
+ deps = ctx.rule.attr.deps + ctx.attr._upb
+ dep_ccinfos = [dep[CcInfo] for dep in deps if CcInfo in dep]
+ dep_ccinfos += [dep[_WrappedCcInfo].cc_info for dep in deps if _WrappedCcInfo in dep]
+ cc_info = _cc_library_func(
+ ctx = ctx,
+ name = ctx.rule.attr.name + ctx.attr._ext,
+ hdrs = files.hdrs,
+ srcs = files.srcs,
+ dep_ccinfos = dep_ccinfos,
+ )
+ return [_WrappedCcInfo(cc_info = cc_info), _WrappedGeneratedSrcsInfo(srcs = files)]
+
+def _maybe_add(d):
+ if not _is_bazel:
+ d["_grep_includes"] = attr.label(
+ allow_single_file = True,
+ cfg = "host",
+ default = "//tools/cpp:grep-includes",
+ )
+ return d
+
+# upb_proto_library() ##########################################################
+
+_upb_proto_library_aspect = aspect(
+ attrs = _maybe_add({
+ "_upbc": attr.label(
+ executable = True,
+ cfg = "host",
+ default = "//:protoc-gen-upb",
+ ),
+ "_protoc": attr.label(
+ executable = True,
+ cfg = "host",
+ default = "@com_google_protobuf//:protoc",
+ ),
+ "_cc_toolchain": attr.label(
+ default = "@bazel_tools//tools/cpp:current_cc_toolchain",
+ ),
+ "_upb": attr.label_list(default = [
+ "//:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
+ "//:upb"
+ ]),
+ "_ext": attr.string(default = ".upb"),
+ }),
+ implementation = _upb_proto_aspect_impl,
+ attr_aspects = ["deps"],
+ fragments = ["cpp"],
+ toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
+)
+
+upb_proto_library = rule(
+ output_to_genfiles = True,
+ implementation = _upb_proto_rule_impl,
+ attrs = {
+ "deps": attr.label_list(
+ aspects = [_upb_proto_library_aspect],
+ allow_rules = ["proto_library"],
+ providers = [ProtoInfo],
+ ),
+ },
+)
+
+# upb_proto_reflection_library() ###############################################
+
+_upb_proto_reflection_library_aspect = aspect(
+ attrs = _maybe_add({
+ "_upbc": attr.label(
+ executable = True,
+ cfg = "host",
+ default = "//:protoc-gen-upb",
+ ),
+ "_protoc": attr.label(
+ executable = True,
+ cfg = "host",
+ default = "@com_google_protobuf//:protoc",
+ ),
+ "_cc_toolchain": attr.label(
+ default = "@bazel_tools//tools/cpp:current_cc_toolchain",
+ ),
+ "_upb": attr.label_list(
+ default = [
+ "//:upb",
+ "//:reflection",
+ ],
+ ),
+ "_ext": attr.string(default = ".upbdefs"),
+ }),
+ implementation = _upb_proto_aspect_impl,
+ attr_aspects = ["deps"],
+ fragments = ["cpp"],
+ toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
+)
+
+upb_proto_reflection_library = rule(
+ output_to_genfiles = True,
+ implementation = _upb_proto_rule_impl,
+ attrs = {
+ "deps": attr.label_list(
+ aspects = [_upb_proto_reflection_library_aspect],
+ allow_rules = ["proto_library"],
+ providers = [ProtoInfo],
+ ),
+ },
+)
diff --git a/third_party/upb/bazel/workspace_deps.bzl b/third_party/upb/bazel/workspace_deps.bzl
new file mode 100644
index 00000000000..39bf524a7a1
--- /dev/null
+++ b/third_party/upb/bazel/workspace_deps.bzl
@@ -0,0 +1,36 @@
+
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
+load("//bazel:repository_defs.bzl", "bazel_version_repository")
+
+def upb_deps():
+ bazel_version_repository(
+ name = "bazel_version",
+ )
+
+ git_repository(
+ name = "absl",
+ commit = "070f6e47b33a2909d039e620c873204f78809492",
+ remote = "https://github.com/abseil/abseil-cpp.git",
+ shallow_since = "1541627663 -0500",
+ )
+
+ git_repository(
+ name = "com_google_protobuf",
+ remote = "https://github.com/protocolbuffers/protobuf.git",
+ commit = "d41002663fd04325ead28439dfd5ce2822b0d6fb",
+ )
+
+ http_archive(
+ name = "bazel_skylib",
+ strip_prefix = "bazel-skylib-master",
+ urls = ["https://github.com/bazelbuild/bazel-skylib/archive/master.tar.gz"],
+ )
+
+ http_archive(
+ name = "zlib",
+ build_file = "@com_google_protobuf//:third_party/zlib.BUILD",
+ sha256 = "c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1",
+ strip_prefix = "zlib-1.2.11",
+ urls = ["https://zlib.net/zlib-1.2.11.tar.gz"],
+ )
diff --git a/third_party/upb/examples/bazel/BUILD b/third_party/upb/examples/bazel/BUILD
new file mode 100644
index 00000000000..94bcfe64d4f
--- /dev/null
+++ b/third_party/upb/examples/bazel/BUILD
@@ -0,0 +1,18 @@
+
+load("@upb//bazel:upb_proto_library.bzl", "upb_proto_library")
+
+proto_library(
+ name = "foo_proto",
+ srcs = ["foo.proto"],
+)
+
+upb_proto_library(
+ name = "foo_upbproto",
+ deps = [":foo_proto"],
+)
+
+cc_binary(
+ name = "test_binary",
+ srcs = ["test_binary.c"],
+ deps = [":foo_upbproto"],
+)
diff --git a/third_party/upb/examples/bazel/WORKSPACE b/third_party/upb/examples/bazel/WORKSPACE
new file mode 100644
index 00000000000..5dfe68ac25a
--- /dev/null
+++ b/third_party/upb/examples/bazel/WORKSPACE
@@ -0,0 +1,14 @@
+
+workspace(name = "upb_example")
+
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
+
+git_repository(
+ name = "upb",
+ remote = "https://github.com/protocolbuffers/upb.git",
+ commit = "d16bf99ac4658793748cda3251226059892b3b7b",
+)
+
+load("@upb//bazel:workspace_deps.bzl", "upb_deps")
+
+upb_deps()
diff --git a/third_party/upb/examples/bazel/foo.proto b/third_party/upb/examples/bazel/foo.proto
new file mode 100644
index 00000000000..f68b99443dd
--- /dev/null
+++ b/third_party/upb/examples/bazel/foo.proto
@@ -0,0 +1,7 @@
+
+syntax = "proto2";
+
+message Foo {
+ optional int64 time = 1;
+ optional string greeting = 2;
+}
diff --git a/third_party/upb/examples/bazel/test_binary.c b/third_party/upb/examples/bazel/test_binary.c
new file mode 100644
index 00000000000..78f367a3707
--- /dev/null
+++ b/third_party/upb/examples/bazel/test_binary.c
@@ -0,0 +1,17 @@
+
+#include
+
+#include "foo.upb.h"
+
+int main() {
+ upb_arena *arena = upb_arena_new();
+ Foo* foo = Foo_new(arena);
+ const char greeting[] = "Hello, World!\n";
+
+ Foo_set_time(foo, time(NULL));
+ /* Warning: the proto will not copy this, the string data must outlive
+ * the proto. */
+ Foo_set_greeting(foo, upb_strview_makez(greeting));
+
+ upb_arena_free(arena);
+}
diff --git a/third_party/upb/generated_for_cmake/google/protobuf/descriptor.upb.c b/third_party/upb/generated_for_cmake/google/protobuf/descriptor.upb.c
new file mode 100644
index 00000000000..61b9299bb43
--- /dev/null
+++ b/third_party/upb/generated_for_cmake/google/protobuf/descriptor.upb.c
@@ -0,0 +1,485 @@
+/* This file was generated by upbc (the upb compiler) from the input
+ * file:
+ *
+ * google/protobuf/descriptor.proto
+ *
+ * Do not edit -- your changes will be discarded when the file is
+ * regenerated. */
+
+#include
+#include "upb/msg.h"
+#include "google/protobuf/descriptor.upb.h"
+
+#include "upb/port_def.inc"
+
+static const upb_msglayout *const google_protobuf_FileDescriptorSet_submsgs[1] = {
+ &google_protobuf_FileDescriptorProto_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] = {
+ {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
+};
+
+const upb_msglayout google_protobuf_FileDescriptorSet_msginit = {
+ &google_protobuf_FileDescriptorSet_submsgs[0],
+ &google_protobuf_FileDescriptorSet__fields[0],
+ UPB_SIZE(4, 8), 1, false,
+};
+
+static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6] = {
+ &google_protobuf_DescriptorProto_msginit,
+ &google_protobuf_EnumDescriptorProto_msginit,
+ &google_protobuf_FieldDescriptorProto_msginit,
+ &google_protobuf_FileOptions_msginit,
+ &google_protobuf_ServiceDescriptorProto_msginit,
+ &google_protobuf_SourceCodeInfo_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12] = {
+ {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
+ {2, UPB_SIZE(12, 24), 2, 0, 9, 1},
+ {3, UPB_SIZE(36, 72), 0, 0, 9, 3},
+ {4, UPB_SIZE(40, 80), 0, 0, 11, 3},
+ {5, UPB_SIZE(44, 88), 0, 1, 11, 3},
+ {6, UPB_SIZE(48, 96), 0, 4, 11, 3},
+ {7, UPB_SIZE(52, 104), 0, 2, 11, 3},
+ {8, UPB_SIZE(28, 56), 4, 3, 11, 1},
+ {9, UPB_SIZE(32, 64), 5, 5, 11, 1},
+ {10, UPB_SIZE(56, 112), 0, 0, 5, 3},
+ {11, UPB_SIZE(60, 120), 0, 0, 5, 3},
+ {12, UPB_SIZE(20, 40), 3, 0, 9, 1},
+};
+
+const upb_msglayout google_protobuf_FileDescriptorProto_msginit = {
+ &google_protobuf_FileDescriptorProto_submsgs[0],
+ &google_protobuf_FileDescriptorProto__fields[0],
+ UPB_SIZE(64, 128), 12, false,
+};
+
+static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[8] = {
+ &google_protobuf_DescriptorProto_msginit,
+ &google_protobuf_DescriptorProto_ExtensionRange_msginit,
+ &google_protobuf_DescriptorProto_ReservedRange_msginit,
+ &google_protobuf_EnumDescriptorProto_msginit,
+ &google_protobuf_FieldDescriptorProto_msginit,
+ &google_protobuf_MessageOptions_msginit,
+ &google_protobuf_OneofDescriptorProto_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = {
+ {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
+ {2, UPB_SIZE(16, 32), 0, 4, 11, 3},
+ {3, UPB_SIZE(20, 40), 0, 0, 11, 3},
+ {4, UPB_SIZE(24, 48), 0, 3, 11, 3},
+ {5, UPB_SIZE(28, 56), 0, 1, 11, 3},
+ {6, UPB_SIZE(32, 64), 0, 4, 11, 3},
+ {7, UPB_SIZE(12, 24), 2, 5, 11, 1},
+ {8, UPB_SIZE(36, 72), 0, 6, 11, 3},
+ {9, UPB_SIZE(40, 80), 0, 2, 11, 3},
+ {10, UPB_SIZE(44, 88), 0, 0, 9, 3},
+};
+
+const upb_msglayout google_protobuf_DescriptorProto_msginit = {
+ &google_protobuf_DescriptorProto_submsgs[0],
+ &google_protobuf_DescriptorProto__fields[0],
+ UPB_SIZE(48, 96), 10, false,
+};
+
+static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = {
+ &google_protobuf_ExtensionRangeOptions_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange__fields[3] = {
+ {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
+ {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
+ {3, UPB_SIZE(12, 16), 3, 0, 11, 1},
+};
+
+const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = {
+ &google_protobuf_DescriptorProto_ExtensionRange_submsgs[0],
+ &google_protobuf_DescriptorProto_ExtensionRange__fields[0],
+ UPB_SIZE(16, 24), 3, false,
+};
+
+static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2] = {
+ {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
+ {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
+};
+
+const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = {
+ NULL,
+ &google_protobuf_DescriptorProto_ReservedRange__fields[0],
+ UPB_SIZE(12, 12), 2, false,
+};
+
+static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1] = {
+ &google_protobuf_UninterpretedOption_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1] = {
+ {999, UPB_SIZE(0, 0), 0, 0, 11, 3},
+};
+
+const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = {
+ &google_protobuf_ExtensionRangeOptions_submsgs[0],
+ &google_protobuf_ExtensionRangeOptions__fields[0],
+ UPB_SIZE(4, 8), 1, false,
+};
+
+static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1] = {
+ &google_protobuf_FieldOptions_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[10] = {
+ {1, UPB_SIZE(32, 32), 5, 0, 9, 1},
+ {2, UPB_SIZE(40, 48), 6, 0, 9, 1},
+ {3, UPB_SIZE(24, 24), 3, 0, 5, 1},
+ {4, UPB_SIZE(8, 8), 1, 0, 14, 1},
+ {5, UPB_SIZE(16, 16), 2, 0, 14, 1},
+ {6, UPB_SIZE(48, 64), 7, 0, 9, 1},
+ {7, UPB_SIZE(56, 80), 8, 0, 9, 1},
+ {8, UPB_SIZE(72, 112), 10, 0, 11, 1},
+ {9, UPB_SIZE(28, 28), 4, 0, 5, 1},
+ {10, UPB_SIZE(64, 96), 9, 0, 9, 1},
+};
+
+const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = {
+ &google_protobuf_FieldDescriptorProto_submsgs[0],
+ &google_protobuf_FieldDescriptorProto__fields[0],
+ UPB_SIZE(80, 128), 10, false,
+};
+
+static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = {
+ &google_protobuf_OneofOptions_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2] = {
+ {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
+ {2, UPB_SIZE(12, 24), 2, 0, 11, 1},
+};
+
+const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = {
+ &google_protobuf_OneofDescriptorProto_submsgs[0],
+ &google_protobuf_OneofDescriptorProto__fields[0],
+ UPB_SIZE(16, 32), 2, false,
+};
+
+static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3] = {
+ &google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit,
+ &google_protobuf_EnumOptions_msginit,
+ &google_protobuf_EnumValueDescriptorProto_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5] = {
+ {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
+ {2, UPB_SIZE(16, 32), 0, 2, 11, 3},
+ {3, UPB_SIZE(12, 24), 2, 1, 11, 1},
+ {4, UPB_SIZE(20, 40), 0, 0, 11, 3},
+ {5, UPB_SIZE(24, 48), 0, 0, 9, 3},
+};
+
+const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = {
+ &google_protobuf_EnumDescriptorProto_submsgs[0],
+ &google_protobuf_EnumDescriptorProto__fields[0],
+ UPB_SIZE(32, 64), 5, false,
+};
+
+static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = {
+ {1, UPB_SIZE(4, 4), 1, 0, 5, 1},
+ {2, UPB_SIZE(8, 8), 2, 0, 5, 1},
+};
+
+const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = {
+ NULL,
+ &google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0],
+ UPB_SIZE(12, 12), 2, false,
+};
+
+static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1] = {
+ &google_protobuf_EnumValueOptions_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = {
+ {1, UPB_SIZE(8, 8), 2, 0, 9, 1},
+ {2, UPB_SIZE(4, 4), 1, 0, 5, 1},
+ {3, UPB_SIZE(16, 24), 3, 0, 11, 1},
+};
+
+const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = {
+ &google_protobuf_EnumValueDescriptorProto_submsgs[0],
+ &google_protobuf_EnumValueDescriptorProto__fields[0],
+ UPB_SIZE(24, 32), 3, false,
+};
+
+static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2] = {
+ &google_protobuf_MethodDescriptorProto_msginit,
+ &google_protobuf_ServiceOptions_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[3] = {
+ {1, UPB_SIZE(4, 8), 1, 0, 9, 1},
+ {2, UPB_SIZE(16, 32), 0, 0, 11, 3},
+ {3, UPB_SIZE(12, 24), 2, 1, 11, 1},
+};
+
+const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = {
+ &google_protobuf_ServiceDescriptorProto_submsgs[0],
+ &google_protobuf_ServiceDescriptorProto__fields[0],
+ UPB_SIZE(24, 48), 3, false,
+};
+
+static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1] = {
+ &google_protobuf_MethodOptions_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = {
+ {1, UPB_SIZE(4, 8), 3, 0, 9, 1},
+ {2, UPB_SIZE(12, 24), 4, 0, 9, 1},
+ {3, UPB_SIZE(20, 40), 5, 0, 9, 1},
+ {4, UPB_SIZE(28, 56), 6, 0, 11, 1},
+ {5, UPB_SIZE(1, 1), 1, 0, 8, 1},
+ {6, UPB_SIZE(2, 2), 2, 0, 8, 1},
+};
+
+const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = {
+ &google_protobuf_MethodDescriptorProto_submsgs[0],
+ &google_protobuf_MethodDescriptorProto__fields[0],
+ UPB_SIZE(32, 64), 6, false,
+};
+
+static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = {
+ &google_protobuf_UninterpretedOption_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = {
+ {1, UPB_SIZE(28, 32), 11, 0, 9, 1},
+ {8, UPB_SIZE(36, 48), 12, 0, 9, 1},
+ {9, UPB_SIZE(8, 8), 1, 0, 14, 1},
+ {10, UPB_SIZE(16, 16), 2, 0, 8, 1},
+ {11, UPB_SIZE(44, 64), 13, 0, 9, 1},
+ {16, UPB_SIZE(17, 17), 3, 0, 8, 1},
+ {17, UPB_SIZE(18, 18), 4, 0, 8, 1},
+ {18, UPB_SIZE(19, 19), 5, 0, 8, 1},
+ {20, UPB_SIZE(20, 20), 6, 0, 8, 1},
+ {23, UPB_SIZE(21, 21), 7, 0, 8, 1},
+ {27, UPB_SIZE(22, 22), 8, 0, 8, 1},
+ {31, UPB_SIZE(23, 23), 9, 0, 8, 1},
+ {36, UPB_SIZE(52, 80), 14, 0, 9, 1},
+ {37, UPB_SIZE(60, 96), 15, 0, 9, 1},
+ {39, UPB_SIZE(68, 112), 16, 0, 9, 1},
+ {40, UPB_SIZE(76, 128), 17, 0, 9, 1},
+ {41, UPB_SIZE(84, 144), 18, 0, 9, 1},
+ {42, UPB_SIZE(24, 24), 10, 0, 8, 1},
+ {44, UPB_SIZE(92, 160), 19, 0, 9, 1},
+ {45, UPB_SIZE(100, 176), 20, 0, 9, 1},
+ {999, UPB_SIZE(108, 192), 0, 0, 11, 3},
+};
+
+const upb_msglayout google_protobuf_FileOptions_msginit = {
+ &google_protobuf_FileOptions_submsgs[0],
+ &google_protobuf_FileOptions__fields[0],
+ UPB_SIZE(112, 208), 21, false,
+};
+
+static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = {
+ &google_protobuf_UninterpretedOption_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = {
+ {1, UPB_SIZE(1, 1), 1, 0, 8, 1},
+ {2, UPB_SIZE(2, 2), 2, 0, 8, 1},
+ {3, UPB_SIZE(3, 3), 3, 0, 8, 1},
+ {7, UPB_SIZE(4, 4), 4, 0, 8, 1},
+ {999, UPB_SIZE(8, 8), 0, 0, 11, 3},
+};
+
+const upb_msglayout google_protobuf_MessageOptions_msginit = {
+ &google_protobuf_MessageOptions_submsgs[0],
+ &google_protobuf_MessageOptions__fields[0],
+ UPB_SIZE(12, 16), 5, false,
+};
+
+static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = {
+ &google_protobuf_UninterpretedOption_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = {
+ {1, UPB_SIZE(8, 8), 1, 0, 14, 1},
+ {2, UPB_SIZE(24, 24), 3, 0, 8, 1},
+ {3, UPB_SIZE(25, 25), 4, 0, 8, 1},
+ {5, UPB_SIZE(26, 26), 5, 0, 8, 1},
+ {6, UPB_SIZE(16, 16), 2, 0, 14, 1},
+ {10, UPB_SIZE(27, 27), 6, 0, 8, 1},
+ {999, UPB_SIZE(28, 32), 0, 0, 11, 3},
+};
+
+const upb_msglayout google_protobuf_FieldOptions_msginit = {
+ &google_protobuf_FieldOptions_submsgs[0],
+ &google_protobuf_FieldOptions__fields[0],
+ UPB_SIZE(32, 40), 7, false,
+};
+
+static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = {
+ &google_protobuf_UninterpretedOption_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = {
+ {999, UPB_SIZE(0, 0), 0, 0, 11, 3},
+};
+
+const upb_msglayout google_protobuf_OneofOptions_msginit = {
+ &google_protobuf_OneofOptions_submsgs[0],
+ &google_protobuf_OneofOptions__fields[0],
+ UPB_SIZE(4, 8), 1, false,
+};
+
+static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = {
+ &google_protobuf_UninterpretedOption_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = {
+ {2, UPB_SIZE(1, 1), 1, 0, 8, 1},
+ {3, UPB_SIZE(2, 2), 2, 0, 8, 1},
+ {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
+};
+
+const upb_msglayout google_protobuf_EnumOptions_msginit = {
+ &google_protobuf_EnumOptions_submsgs[0],
+ &google_protobuf_EnumOptions__fields[0],
+ UPB_SIZE(8, 16), 3, false,
+};
+
+static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] = {
+ &google_protobuf_UninterpretedOption_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = {
+ {1, UPB_SIZE(1, 1), 1, 0, 8, 1},
+ {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
+};
+
+const upb_msglayout google_protobuf_EnumValueOptions_msginit = {
+ &google_protobuf_EnumValueOptions_submsgs[0],
+ &google_protobuf_EnumValueOptions__fields[0],
+ UPB_SIZE(8, 16), 2, false,
+};
+
+static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = {
+ &google_protobuf_UninterpretedOption_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = {
+ {33, UPB_SIZE(1, 1), 1, 0, 8, 1},
+ {999, UPB_SIZE(4, 8), 0, 0, 11, 3},
+};
+
+const upb_msglayout google_protobuf_ServiceOptions_msginit = {
+ &google_protobuf_ServiceOptions_submsgs[0],
+ &google_protobuf_ServiceOptions__fields[0],
+ UPB_SIZE(8, 16), 2, false,
+};
+
+static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = {
+ &google_protobuf_UninterpretedOption_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = {
+ {33, UPB_SIZE(16, 16), 2, 0, 8, 1},
+ {34, UPB_SIZE(8, 8), 1, 0, 14, 1},
+ {999, UPB_SIZE(20, 24), 0, 0, 11, 3},
+};
+
+const upb_msglayout google_protobuf_MethodOptions_msginit = {
+ &google_protobuf_MethodOptions_submsgs[0],
+ &google_protobuf_MethodOptions__fields[0],
+ UPB_SIZE(24, 32), 3, false,
+};
+
+static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] = {
+ &google_protobuf_UninterpretedOption_NamePart_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = {
+ {2, UPB_SIZE(56, 80), 0, 0, 11, 3},
+ {3, UPB_SIZE(32, 32), 4, 0, 9, 1},
+ {4, UPB_SIZE(8, 8), 1, 0, 4, 1},
+ {5, UPB_SIZE(16, 16), 2, 0, 3, 1},
+ {6, UPB_SIZE(24, 24), 3, 0, 1, 1},
+ {7, UPB_SIZE(40, 48), 5, 0, 12, 1},
+ {8, UPB_SIZE(48, 64), 6, 0, 9, 1},
+};
+
+const upb_msglayout google_protobuf_UninterpretedOption_msginit = {
+ &google_protobuf_UninterpretedOption_submsgs[0],
+ &google_protobuf_UninterpretedOption__fields[0],
+ UPB_SIZE(64, 96), 7, false,
+};
+
+static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = {
+ {1, UPB_SIZE(4, 8), 2, 0, 9, 2},
+ {2, UPB_SIZE(1, 1), 1, 0, 8, 2},
+};
+
+const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = {
+ NULL,
+ &google_protobuf_UninterpretedOption_NamePart__fields[0],
+ UPB_SIZE(16, 32), 2, false,
+};
+
+static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = {
+ &google_protobuf_SourceCodeInfo_Location_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = {
+ {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
+};
+
+const upb_msglayout google_protobuf_SourceCodeInfo_msginit = {
+ &google_protobuf_SourceCodeInfo_submsgs[0],
+ &google_protobuf_SourceCodeInfo__fields[0],
+ UPB_SIZE(4, 8), 1, false,
+};
+
+static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = {
+ {1, UPB_SIZE(20, 40), 0, 0, 5, 3},
+ {2, UPB_SIZE(24, 48), 0, 0, 5, 3},
+ {3, UPB_SIZE(4, 8), 1, 0, 9, 1},
+ {4, UPB_SIZE(12, 24), 2, 0, 9, 1},
+ {6, UPB_SIZE(28, 56), 0, 0, 9, 3},
+};
+
+const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = {
+ NULL,
+ &google_protobuf_SourceCodeInfo_Location__fields[0],
+ UPB_SIZE(32, 64), 5, false,
+};
+
+static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] = {
+ &google_protobuf_GeneratedCodeInfo_Annotation_msginit,
+};
+
+static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] = {
+ {1, UPB_SIZE(0, 0), 0, 0, 11, 3},
+};
+
+const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = {
+ &google_protobuf_GeneratedCodeInfo_submsgs[0],
+ &google_protobuf_GeneratedCodeInfo__fields[0],
+ UPB_SIZE(4, 8), 1, false,
+};
+
+static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = {
+ {1, UPB_SIZE(20, 32), 0, 0, 5, 3},
+ {2, UPB_SIZE(12, 16), 3, 0, 9, 1},
+ {3, UPB_SIZE(4, 4), 1, 0, 5, 1},
+ {4, UPB_SIZE(8, 8), 2, 0, 5, 1},
+};
+
+const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = {
+ NULL,
+ &google_protobuf_GeneratedCodeInfo_Annotation__fields[0],
+ UPB_SIZE(24, 48), 4, false,
+};
+
+#include "upb/port_undef.inc"
+
diff --git a/third_party/upb/generated_for_cmake/google/protobuf/descriptor.upb.h b/third_party/upb/generated_for_cmake/google/protobuf/descriptor.upb.h
new file mode 100644
index 00000000000..681614910e0
--- /dev/null
+++ b/third_party/upb/generated_for_cmake/google/protobuf/descriptor.upb.h
@@ -0,0 +1,1690 @@
+/* This file was generated by upbc (the upb compiler) from the input
+ * file:
+ *
+ * google/protobuf/descriptor.proto
+ *
+ * Do not edit -- your changes will be discarded when the file is
+ * regenerated. */
+
+#ifndef GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_
+#define GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_
+
+#include "upb/generated_util.h"
+#include "upb/msg.h"
+#include "upb/decode.h"
+#include "upb/encode.h"
+
+#include "upb/port_def.inc"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct google_protobuf_FileDescriptorSet;
+struct google_protobuf_FileDescriptorProto;
+struct google_protobuf_DescriptorProto;
+struct google_protobuf_DescriptorProto_ExtensionRange;
+struct google_protobuf_DescriptorProto_ReservedRange;
+struct google_protobuf_ExtensionRangeOptions;
+struct google_protobuf_FieldDescriptorProto;
+struct google_protobuf_OneofDescriptorProto;
+struct google_protobuf_EnumDescriptorProto;
+struct google_protobuf_EnumDescriptorProto_EnumReservedRange;
+struct google_protobuf_EnumValueDescriptorProto;
+struct google_protobuf_ServiceDescriptorProto;
+struct google_protobuf_MethodDescriptorProto;
+struct google_protobuf_FileOptions;
+struct google_protobuf_MessageOptions;
+struct google_protobuf_FieldOptions;
+struct google_protobuf_OneofOptions;
+struct google_protobuf_EnumOptions;
+struct google_protobuf_EnumValueOptions;
+struct google_protobuf_ServiceOptions;
+struct google_protobuf_MethodOptions;
+struct google_protobuf_UninterpretedOption;
+struct google_protobuf_UninterpretedOption_NamePart;
+struct google_protobuf_SourceCodeInfo;
+struct google_protobuf_SourceCodeInfo_Location;
+struct google_protobuf_GeneratedCodeInfo;
+struct google_protobuf_GeneratedCodeInfo_Annotation;
+typedef struct google_protobuf_FileDescriptorSet google_protobuf_FileDescriptorSet;
+typedef struct google_protobuf_FileDescriptorProto google_protobuf_FileDescriptorProto;
+typedef struct google_protobuf_DescriptorProto google_protobuf_DescriptorProto;
+typedef struct google_protobuf_DescriptorProto_ExtensionRange google_protobuf_DescriptorProto_ExtensionRange;
+typedef struct google_protobuf_DescriptorProto_ReservedRange google_protobuf_DescriptorProto_ReservedRange;
+typedef struct google_protobuf_ExtensionRangeOptions google_protobuf_ExtensionRangeOptions;
+typedef struct google_protobuf_FieldDescriptorProto google_protobuf_FieldDescriptorProto;
+typedef struct google_protobuf_OneofDescriptorProto google_protobuf_OneofDescriptorProto;
+typedef struct google_protobuf_EnumDescriptorProto google_protobuf_EnumDescriptorProto;
+typedef struct google_protobuf_EnumDescriptorProto_EnumReservedRange google_protobuf_EnumDescriptorProto_EnumReservedRange;
+typedef struct google_protobuf_EnumValueDescriptorProto google_protobuf_EnumValueDescriptorProto;
+typedef struct google_protobuf_ServiceDescriptorProto google_protobuf_ServiceDescriptorProto;
+typedef struct google_protobuf_MethodDescriptorProto google_protobuf_MethodDescriptorProto;
+typedef struct google_protobuf_FileOptions google_protobuf_FileOptions;
+typedef struct google_protobuf_MessageOptions google_protobuf_MessageOptions;
+typedef struct google_protobuf_FieldOptions google_protobuf_FieldOptions;
+typedef struct google_protobuf_OneofOptions google_protobuf_OneofOptions;
+typedef struct google_protobuf_EnumOptions google_protobuf_EnumOptions;
+typedef struct google_protobuf_EnumValueOptions google_protobuf_EnumValueOptions;
+typedef struct google_protobuf_ServiceOptions google_protobuf_ServiceOptions;
+typedef struct google_protobuf_MethodOptions google_protobuf_MethodOptions;
+typedef struct google_protobuf_UninterpretedOption google_protobuf_UninterpretedOption;
+typedef struct google_protobuf_UninterpretedOption_NamePart google_protobuf_UninterpretedOption_NamePart;
+typedef struct google_protobuf_SourceCodeInfo google_protobuf_SourceCodeInfo;
+typedef struct google_protobuf_SourceCodeInfo_Location google_protobuf_SourceCodeInfo_Location;
+typedef struct google_protobuf_GeneratedCodeInfo google_protobuf_GeneratedCodeInfo;
+typedef struct google_protobuf_GeneratedCodeInfo_Annotation google_protobuf_GeneratedCodeInfo_Annotation;
+extern const upb_msglayout google_protobuf_FileDescriptorSet_msginit;
+extern const upb_msglayout google_protobuf_FileDescriptorProto_msginit;
+extern const upb_msglayout google_protobuf_DescriptorProto_msginit;
+extern const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit;
+extern const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit;
+extern const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit;
+extern const upb_msglayout google_protobuf_FieldDescriptorProto_msginit;
+extern const upb_msglayout google_protobuf_OneofDescriptorProto_msginit;
+extern const upb_msglayout google_protobuf_EnumDescriptorProto_msginit;
+extern const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit;
+extern const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit;
+extern const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit;
+extern const upb_msglayout google_protobuf_MethodDescriptorProto_msginit;
+extern const upb_msglayout google_protobuf_FileOptions_msginit;
+extern const upb_msglayout google_protobuf_MessageOptions_msginit;
+extern const upb_msglayout google_protobuf_FieldOptions_msginit;
+extern const upb_msglayout google_protobuf_OneofOptions_msginit;
+extern const upb_msglayout google_protobuf_EnumOptions_msginit;
+extern const upb_msglayout google_protobuf_EnumValueOptions_msginit;
+extern const upb_msglayout google_protobuf_ServiceOptions_msginit;
+extern const upb_msglayout google_protobuf_MethodOptions_msginit;
+extern const upb_msglayout google_protobuf_UninterpretedOption_msginit;
+extern const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit;
+extern const upb_msglayout google_protobuf_SourceCodeInfo_msginit;
+extern const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit;
+extern const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit;
+extern const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit;
+
+typedef enum {
+ google_protobuf_FieldDescriptorProto_LABEL_OPTIONAL = 1,
+ google_protobuf_FieldDescriptorProto_LABEL_REQUIRED = 2,
+ google_protobuf_FieldDescriptorProto_LABEL_REPEATED = 3
+} google_protobuf_FieldDescriptorProto_Label;
+
+typedef enum {
+ google_protobuf_FieldDescriptorProto_TYPE_DOUBLE = 1,
+ google_protobuf_FieldDescriptorProto_TYPE_FLOAT = 2,
+ google_protobuf_FieldDescriptorProto_TYPE_INT64 = 3,
+ google_protobuf_FieldDescriptorProto_TYPE_UINT64 = 4,
+ google_protobuf_FieldDescriptorProto_TYPE_INT32 = 5,
+ google_protobuf_FieldDescriptorProto_TYPE_FIXED64 = 6,
+ google_protobuf_FieldDescriptorProto_TYPE_FIXED32 = 7,
+ google_protobuf_FieldDescriptorProto_TYPE_BOOL = 8,
+ google_protobuf_FieldDescriptorProto_TYPE_STRING = 9,
+ google_protobuf_FieldDescriptorProto_TYPE_GROUP = 10,
+ google_protobuf_FieldDescriptorProto_TYPE_MESSAGE = 11,
+ google_protobuf_FieldDescriptorProto_TYPE_BYTES = 12,
+ google_protobuf_FieldDescriptorProto_TYPE_UINT32 = 13,
+ google_protobuf_FieldDescriptorProto_TYPE_ENUM = 14,
+ google_protobuf_FieldDescriptorProto_TYPE_SFIXED32 = 15,
+ google_protobuf_FieldDescriptorProto_TYPE_SFIXED64 = 16,
+ google_protobuf_FieldDescriptorProto_TYPE_SINT32 = 17,
+ google_protobuf_FieldDescriptorProto_TYPE_SINT64 = 18
+} google_protobuf_FieldDescriptorProto_Type;
+
+typedef enum {
+ google_protobuf_FieldOptions_STRING = 0,
+ google_protobuf_FieldOptions_CORD = 1,
+ google_protobuf_FieldOptions_STRING_PIECE = 2
+} google_protobuf_FieldOptions_CType;
+
+typedef enum {
+ google_protobuf_FieldOptions_JS_NORMAL = 0,
+ google_protobuf_FieldOptions_JS_STRING = 1,
+ google_protobuf_FieldOptions_JS_NUMBER = 2
+} google_protobuf_FieldOptions_JSType;
+
+typedef enum {
+ google_protobuf_FileOptions_SPEED = 1,
+ google_protobuf_FileOptions_CODE_SIZE = 2,
+ google_protobuf_FileOptions_LITE_RUNTIME = 3
+} google_protobuf_FileOptions_OptimizeMode;
+
+typedef enum {
+ google_protobuf_MethodOptions_IDEMPOTENCY_UNKNOWN = 0,
+ google_protobuf_MethodOptions_NO_SIDE_EFFECTS = 1,
+ google_protobuf_MethodOptions_IDEMPOTENT = 2
+} google_protobuf_MethodOptions_IdempotencyLevel;
+
+
+/* google.protobuf.FileDescriptorSet */
+
+UPB_INLINE google_protobuf_FileDescriptorSet *google_protobuf_FileDescriptorSet_new(upb_arena *arena) {
+ return (google_protobuf_FileDescriptorSet *)upb_msg_new(&google_protobuf_FileDescriptorSet_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE const google_protobuf_FileDescriptorProto* const* google_protobuf_FileDescriptorSet_file(const google_protobuf_FileDescriptorSet *msg, size_t *len) { return (const google_protobuf_FileDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); }
+
+UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorSet_mutable_file(google_protobuf_FileDescriptorSet *msg, size_t *len) {
+ return (google_protobuf_FileDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
+}
+UPB_INLINE google_protobuf_FileDescriptorProto** google_protobuf_FileDescriptorSet_resize_file(google_protobuf_FileDescriptorSet *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_FileDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_FileDescriptorProto* google_protobuf_FileDescriptorSet_add_file(google_protobuf_FileDescriptorSet *msg, upb_arena *arena) {
+ struct google_protobuf_FileDescriptorProto* sub = (struct google_protobuf_FileDescriptorProto*)upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+
+/* google.protobuf.FileDescriptorProto */
+
+UPB_INLINE google_protobuf_FileDescriptorProto *google_protobuf_FileDescriptorProto_new(upb_arena *arena) {
+ return (google_protobuf_FileDescriptorProto *)upb_msg_new(&google_protobuf_FileDescriptorProto_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_FileDescriptorProto_has_name(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_name(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); }
+UPB_INLINE bool google_protobuf_FileDescriptorProto_has_package(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_package(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)); }
+UPB_INLINE upb_strview const* google_protobuf_FileDescriptorProto_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); }
+UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_FileDescriptorProto_message_type(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); }
+UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_FileDescriptorProto_enum_type(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); }
+UPB_INLINE const google_protobuf_ServiceDescriptorProto* const* google_protobuf_FileDescriptorProto_service(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_ServiceDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(48, 96), len); }
+UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_FileDescriptorProto_extension(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(52, 104), len); }
+UPB_INLINE bool google_protobuf_FileDescriptorProto_has_options(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 4); }
+UPB_INLINE const google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_options(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_FileOptions*, UPB_SIZE(28, 56)); }
+UPB_INLINE bool google_protobuf_FileDescriptorProto_has_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 5); }
+UPB_INLINE const google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_source_code_info(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_SourceCodeInfo*, UPB_SIZE(32, 64)); }
+UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_public_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(56, 112), len); }
+UPB_INLINE int32_t const* google_protobuf_FileDescriptorProto_weak_dependency(const google_protobuf_FileDescriptorProto *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(60, 120), len); }
+UPB_INLINE bool google_protobuf_FileDescriptorProto_has_syntax(const google_protobuf_FileDescriptorProto *msg) { return _upb_has_field(msg, 3); }
+UPB_INLINE upb_strview google_protobuf_FileDescriptorProto_syntax(const google_protobuf_FileDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)); }
+
+UPB_INLINE void google_protobuf_FileDescriptorProto_set_name(google_protobuf_FileDescriptorProto *msg, upb_strview value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value;
+}
+UPB_INLINE void google_protobuf_FileDescriptorProto_set_package(google_protobuf_FileDescriptorProto *msg, upb_strview value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)) = value;
+}
+UPB_INLINE upb_strview* google_protobuf_FileDescriptorProto_mutable_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) {
+ return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len);
+}
+UPB_INLINE upb_strview* google_protobuf_FileDescriptorProto_resize_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena);
+}
+UPB_INLINE bool google_protobuf_FileDescriptorProto_add_dependency(google_protobuf_FileDescriptorProto *msg, upb_strview val, upb_arena *arena) {
+ return _upb_array_append_accessor(
+ msg, UPB_SIZE(36, 72), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena);
+}
+UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_mutable_message_type(google_protobuf_FileDescriptorProto *msg, size_t *len) {
+ return (google_protobuf_DescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
+}
+UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_FileDescriptorProto_resize_message_type(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_FileDescriptorProto_add_message_type(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_mutable_enum_type(google_protobuf_FileDescriptorProto *msg, size_t *len) {
+ return (google_protobuf_EnumDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len);
+}
+UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_FileDescriptorProto_resize_enum_type(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_FileDescriptorProto_add_enum_type(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(44, 88), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_mutable_service(google_protobuf_FileDescriptorProto *msg, size_t *len) {
+ return (google_protobuf_ServiceDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 96), len);
+}
+UPB_INLINE google_protobuf_ServiceDescriptorProto** google_protobuf_FileDescriptorProto_resize_service(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_ServiceDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(48, 96), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_ServiceDescriptorProto* google_protobuf_FileDescriptorProto_add_service(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_ServiceDescriptorProto* sub = (struct google_protobuf_ServiceDescriptorProto*)upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(48, 96), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_mutable_extension(google_protobuf_FileDescriptorProto *msg, size_t *len) {
+ return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 104), len);
+}
+UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_FileDescriptorProto_resize_extension(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(52, 104), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_FileDescriptorProto_add_extension(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(52, 104), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+UPB_INLINE void google_protobuf_FileDescriptorProto_set_options(google_protobuf_FileDescriptorProto *msg, google_protobuf_FileOptions* value) {
+ _upb_sethas(msg, 4);
+ UPB_FIELD_AT(msg, google_protobuf_FileOptions*, UPB_SIZE(28, 56)) = value;
+}
+UPB_INLINE struct google_protobuf_FileOptions* google_protobuf_FileDescriptorProto_mutable_options(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_FileOptions* sub = (struct google_protobuf_FileOptions*)google_protobuf_FileDescriptorProto_options(msg);
+ if (sub == NULL) {
+ sub = (struct google_protobuf_FileOptions*)upb_msg_new(&google_protobuf_FileOptions_msginit, arena);
+ if (!sub) return NULL;
+ google_protobuf_FileDescriptorProto_set_options(msg, sub);
+ }
+ return sub;
+}
+UPB_INLINE void google_protobuf_FileDescriptorProto_set_source_code_info(google_protobuf_FileDescriptorProto *msg, google_protobuf_SourceCodeInfo* value) {
+ _upb_sethas(msg, 5);
+ UPB_FIELD_AT(msg, google_protobuf_SourceCodeInfo*, UPB_SIZE(32, 64)) = value;
+}
+UPB_INLINE struct google_protobuf_SourceCodeInfo* google_protobuf_FileDescriptorProto_mutable_source_code_info(google_protobuf_FileDescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_SourceCodeInfo* sub = (struct google_protobuf_SourceCodeInfo*)google_protobuf_FileDescriptorProto_source_code_info(msg);
+ if (sub == NULL) {
+ sub = (struct google_protobuf_SourceCodeInfo*)upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena);
+ if (!sub) return NULL;
+ google_protobuf_FileDescriptorProto_set_source_code_info(msg, sub);
+ }
+ return sub;
+}
+UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_public_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) {
+ return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 112), len);
+}
+UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_public_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(56, 112), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena);
+}
+UPB_INLINE bool google_protobuf_FileDescriptorProto_add_public_dependency(google_protobuf_FileDescriptorProto *msg, int32_t val, upb_arena *arena) {
+ return _upb_array_append_accessor(
+ msg, UPB_SIZE(56, 112), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena);
+}
+UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_mutable_weak_dependency(google_protobuf_FileDescriptorProto *msg, size_t *len) {
+ return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(60, 120), len);
+}
+UPB_INLINE int32_t* google_protobuf_FileDescriptorProto_resize_weak_dependency(google_protobuf_FileDescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(60, 120), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena);
+}
+UPB_INLINE bool google_protobuf_FileDescriptorProto_add_weak_dependency(google_protobuf_FileDescriptorProto *msg, int32_t val, upb_arena *arena) {
+ return _upb_array_append_accessor(
+ msg, UPB_SIZE(60, 120), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena);
+}
+UPB_INLINE void google_protobuf_FileDescriptorProto_set_syntax(google_protobuf_FileDescriptorProto *msg, upb_strview value) {
+ _upb_sethas(msg, 3);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)) = value;
+}
+
+/* google.protobuf.DescriptorProto */
+
+UPB_INLINE google_protobuf_DescriptorProto *google_protobuf_DescriptorProto_new(upb_arena *arena) {
+ return (google_protobuf_DescriptorProto *)upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_DescriptorProto_has_name(const google_protobuf_DescriptorProto *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE upb_strview google_protobuf_DescriptorProto_name(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); }
+UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_field(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
+UPB_INLINE const google_protobuf_DescriptorProto* const* google_protobuf_DescriptorProto_nested_type(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); }
+UPB_INLINE const google_protobuf_EnumDescriptorProto* const* google_protobuf_DescriptorProto_enum_type(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); }
+UPB_INLINE const google_protobuf_DescriptorProto_ExtensionRange* const* google_protobuf_DescriptorProto_extension_range(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto_ExtensionRange* const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); }
+UPB_INLINE const google_protobuf_FieldDescriptorProto* const* google_protobuf_DescriptorProto_extension(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_FieldDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(32, 64), len); }
+UPB_INLINE bool google_protobuf_DescriptorProto_has_options(const google_protobuf_DescriptorProto *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE const google_protobuf_MessageOptions* google_protobuf_DescriptorProto_options(const google_protobuf_DescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_MessageOptions*, UPB_SIZE(12, 24)); }
+UPB_INLINE const google_protobuf_OneofDescriptorProto* const* google_protobuf_DescriptorProto_oneof_decl(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_OneofDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(36, 72), len); }
+UPB_INLINE const google_protobuf_DescriptorProto_ReservedRange* const* google_protobuf_DescriptorProto_reserved_range(const google_protobuf_DescriptorProto *msg, size_t *len) { return (const google_protobuf_DescriptorProto_ReservedRange* const*)_upb_array_accessor(msg, UPB_SIZE(40, 80), len); }
+UPB_INLINE upb_strview const* google_protobuf_DescriptorProto_reserved_name(const google_protobuf_DescriptorProto *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(44, 88), len); }
+
+UPB_INLINE void google_protobuf_DescriptorProto_set_name(google_protobuf_DescriptorProto *msg, upb_strview value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value;
+}
+UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_mutable_field(google_protobuf_DescriptorProto *msg, size_t *len) {
+ return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
+}
+UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_field(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_field(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_mutable_nested_type(google_protobuf_DescriptorProto *msg, size_t *len) {
+ return (google_protobuf_DescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
+}
+UPB_INLINE google_protobuf_DescriptorProto** google_protobuf_DescriptorProto_resize_nested_type(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_DescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_DescriptorProto* google_protobuf_DescriptorProto_add_nested_type(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_DescriptorProto* sub = (struct google_protobuf_DescriptorProto*)upb_msg_new(&google_protobuf_DescriptorProto_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_mutable_enum_type(google_protobuf_DescriptorProto *msg, size_t *len) {
+ return (google_protobuf_EnumDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
+}
+UPB_INLINE google_protobuf_EnumDescriptorProto** google_protobuf_DescriptorProto_resize_enum_type(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_EnumDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_EnumDescriptorProto* google_protobuf_DescriptorProto_add_enum_type(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_EnumDescriptorProto* sub = (struct google_protobuf_EnumDescriptorProto*)upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(24, 48), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_mutable_extension_range(google_protobuf_DescriptorProto *msg, size_t *len) {
+ return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
+}
+UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange** google_protobuf_DescriptorProto_resize_extension_range(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_DescriptorProto_ExtensionRange**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_DescriptorProto_ExtensionRange* google_protobuf_DescriptorProto_add_extension_range(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_DescriptorProto_ExtensionRange* sub = (struct google_protobuf_DescriptorProto_ExtensionRange*)upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(28, 56), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_mutable_extension(google_protobuf_DescriptorProto *msg, size_t *len) {
+ return (google_protobuf_FieldDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(32, 64), len);
+}
+UPB_INLINE google_protobuf_FieldDescriptorProto** google_protobuf_DescriptorProto_resize_extension(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_FieldDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(32, 64), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_FieldDescriptorProto* google_protobuf_DescriptorProto_add_extension(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_FieldDescriptorProto* sub = (struct google_protobuf_FieldDescriptorProto*)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(32, 64), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+UPB_INLINE void google_protobuf_DescriptorProto_set_options(google_protobuf_DescriptorProto *msg, google_protobuf_MessageOptions* value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, google_protobuf_MessageOptions*, UPB_SIZE(12, 24)) = value;
+}
+UPB_INLINE struct google_protobuf_MessageOptions* google_protobuf_DescriptorProto_mutable_options(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_MessageOptions* sub = (struct google_protobuf_MessageOptions*)google_protobuf_DescriptorProto_options(msg);
+ if (sub == NULL) {
+ sub = (struct google_protobuf_MessageOptions*)upb_msg_new(&google_protobuf_MessageOptions_msginit, arena);
+ if (!sub) return NULL;
+ google_protobuf_DescriptorProto_set_options(msg, sub);
+ }
+ return sub;
+}
+UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProto_mutable_oneof_decl(google_protobuf_DescriptorProto *msg, size_t *len) {
+ return (google_protobuf_OneofDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(36, 72), len);
+}
+UPB_INLINE google_protobuf_OneofDescriptorProto** google_protobuf_DescriptorProto_resize_oneof_decl(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_OneofDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(36, 72), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_OneofDescriptorProto* google_protobuf_DescriptorProto_add_oneof_decl(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_OneofDescriptorProto* sub = (struct google_protobuf_OneofDescriptorProto*)upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(36, 72), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_mutable_reserved_range(google_protobuf_DescriptorProto *msg, size_t *len) {
+ return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(40, 80), len);
+}
+UPB_INLINE google_protobuf_DescriptorProto_ReservedRange** google_protobuf_DescriptorProto_resize_reserved_range(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_DescriptorProto_ReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(40, 80), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_DescriptorProto_ReservedRange* google_protobuf_DescriptorProto_add_reserved_range(google_protobuf_DescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_DescriptorProto_ReservedRange* sub = (struct google_protobuf_DescriptorProto_ReservedRange*)upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(40, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+UPB_INLINE upb_strview* google_protobuf_DescriptorProto_mutable_reserved_name(google_protobuf_DescriptorProto *msg, size_t *len) {
+ return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 88), len);
+}
+UPB_INLINE upb_strview* google_protobuf_DescriptorProto_resize_reserved_name(google_protobuf_DescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(44, 88), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena);
+}
+UPB_INLINE bool google_protobuf_DescriptorProto_add_reserved_name(google_protobuf_DescriptorProto *msg, upb_strview val, upb_arena *arena) {
+ return _upb_array_append_accessor(
+ msg, UPB_SIZE(44, 88), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena);
+}
+
+/* google.protobuf.DescriptorProto.ExtensionRange */
+
+UPB_INLINE google_protobuf_DescriptorProto_ExtensionRange *google_protobuf_DescriptorProto_ExtensionRange_new(upb_arena *arena) {
+ return (google_protobuf_DescriptorProto_ExtensionRange *)upb_msg_new(&google_protobuf_DescriptorProto_ExtensionRange_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_start(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); }
+UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE int32_t google_protobuf_DescriptorProto_ExtensionRange_end(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); }
+UPB_INLINE bool google_protobuf_DescriptorProto_ExtensionRange_has_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return _upb_has_field(msg, 3); }
+UPB_INLINE const google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_options(const google_protobuf_DescriptorProto_ExtensionRange *msg) { return UPB_FIELD_AT(msg, const google_protobuf_ExtensionRangeOptions*, UPB_SIZE(12, 16)); }
+
+UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_start(google_protobuf_DescriptorProto_ExtensionRange *msg, int32_t value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value;
+}
+UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_end(google_protobuf_DescriptorProto_ExtensionRange *msg, int32_t value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value;
+}
+UPB_INLINE void google_protobuf_DescriptorProto_ExtensionRange_set_options(google_protobuf_DescriptorProto_ExtensionRange *msg, google_protobuf_ExtensionRangeOptions* value) {
+ _upb_sethas(msg, 3);
+ UPB_FIELD_AT(msg, google_protobuf_ExtensionRangeOptions*, UPB_SIZE(12, 16)) = value;
+}
+UPB_INLINE struct google_protobuf_ExtensionRangeOptions* google_protobuf_DescriptorProto_ExtensionRange_mutable_options(google_protobuf_DescriptorProto_ExtensionRange *msg, upb_arena *arena) {
+ struct google_protobuf_ExtensionRangeOptions* sub = (struct google_protobuf_ExtensionRangeOptions*)google_protobuf_DescriptorProto_ExtensionRange_options(msg);
+ if (sub == NULL) {
+ sub = (struct google_protobuf_ExtensionRangeOptions*)upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena);
+ if (!sub) return NULL;
+ google_protobuf_DescriptorProto_ExtensionRange_set_options(msg, sub);
+ }
+ return sub;
+}
+
+/* google.protobuf.DescriptorProto.ReservedRange */
+
+UPB_INLINE google_protobuf_DescriptorProto_ReservedRange *google_protobuf_DescriptorProto_ReservedRange_new(upb_arena *arena) {
+ return (google_protobuf_DescriptorProto_ReservedRange *)upb_msg_new(&google_protobuf_DescriptorProto_ReservedRange_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_start(const google_protobuf_DescriptorProto_ReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); }
+UPB_INLINE bool google_protobuf_DescriptorProto_ReservedRange_has_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE int32_t google_protobuf_DescriptorProto_ReservedRange_end(const google_protobuf_DescriptorProto_ReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); }
+
+UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_start(google_protobuf_DescriptorProto_ReservedRange *msg, int32_t value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value;
+}
+UPB_INLINE void google_protobuf_DescriptorProto_ReservedRange_set_end(google_protobuf_DescriptorProto_ReservedRange *msg, int32_t value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value;
+}
+
+/* google.protobuf.ExtensionRangeOptions */
+
+UPB_INLINE google_protobuf_ExtensionRangeOptions *google_protobuf_ExtensionRangeOptions_new(upb_arena *arena) {
+ return (google_protobuf_ExtensionRangeOptions *)upb_msg_new(&google_protobuf_ExtensionRangeOptions_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_ExtensionRangeOptions_uninterpreted_option(const google_protobuf_ExtensionRangeOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); }
+
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeOptions_mutable_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, size_t *len) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
+}
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ExtensionRangeOptions_resize_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ExtensionRangeOptions_add_uninterpreted_option(google_protobuf_ExtensionRangeOptions *msg, upb_arena *arena) {
+ struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+
+/* google.protobuf.FieldDescriptorProto */
+
+UPB_INLINE google_protobuf_FieldDescriptorProto *google_protobuf_FieldDescriptorProto_new(upb_arena *arena) {
+ return (google_protobuf_FieldDescriptorProto *)upb_msg_new(&google_protobuf_FieldDescriptorProto_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 5); }
+UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_extendee(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 6); }
+UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_extendee(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_number(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 3); }
+UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_number(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_label(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_label(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_type(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_type_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 7); }
+UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_type_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_default_value(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 8); }
+UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_default_value(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(56, 80)); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_options(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 10); }
+UPB_INLINE const google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_options(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_FieldOptions*, UPB_SIZE(72, 112)); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 4); }
+UPB_INLINE int32_t google_protobuf_FieldDescriptorProto_oneof_index(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(28, 28)); }
+UPB_INLINE bool google_protobuf_FieldDescriptorProto_has_json_name(const google_protobuf_FieldDescriptorProto *msg) { return _upb_has_field(msg, 9); }
+UPB_INLINE upb_strview google_protobuf_FieldDescriptorProto_json_name(const google_protobuf_FieldDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(64, 96)); }
+
+UPB_INLINE void google_protobuf_FieldDescriptorProto_set_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
+ _upb_sethas(msg, 5);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)) = value;
+}
+UPB_INLINE void google_protobuf_FieldDescriptorProto_set_extendee(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
+ _upb_sethas(msg, 6);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)) = value;
+}
+UPB_INLINE void google_protobuf_FieldDescriptorProto_set_number(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
+ _upb_sethas(msg, 3);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(24, 24)) = value;
+}
+UPB_INLINE void google_protobuf_FieldDescriptorProto_set_label(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value;
+}
+UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value;
+}
+UPB_INLINE void google_protobuf_FieldDescriptorProto_set_type_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
+ _upb_sethas(msg, 7);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)) = value;
+}
+UPB_INLINE void google_protobuf_FieldDescriptorProto_set_default_value(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
+ _upb_sethas(msg, 8);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(56, 80)) = value;
+}
+UPB_INLINE void google_protobuf_FieldDescriptorProto_set_options(google_protobuf_FieldDescriptorProto *msg, google_protobuf_FieldOptions* value) {
+ _upb_sethas(msg, 10);
+ UPB_FIELD_AT(msg, google_protobuf_FieldOptions*, UPB_SIZE(72, 112)) = value;
+}
+UPB_INLINE struct google_protobuf_FieldOptions* google_protobuf_FieldDescriptorProto_mutable_options(google_protobuf_FieldDescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_FieldOptions* sub = (struct google_protobuf_FieldOptions*)google_protobuf_FieldDescriptorProto_options(msg);
+ if (sub == NULL) {
+ sub = (struct google_protobuf_FieldOptions*)upb_msg_new(&google_protobuf_FieldOptions_msginit, arena);
+ if (!sub) return NULL;
+ google_protobuf_FieldDescriptorProto_set_options(msg, sub);
+ }
+ return sub;
+}
+UPB_INLINE void google_protobuf_FieldDescriptorProto_set_oneof_index(google_protobuf_FieldDescriptorProto *msg, int32_t value) {
+ _upb_sethas(msg, 4);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(28, 28)) = value;
+}
+UPB_INLINE void google_protobuf_FieldDescriptorProto_set_json_name(google_protobuf_FieldDescriptorProto *msg, upb_strview value) {
+ _upb_sethas(msg, 9);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(64, 96)) = value;
+}
+
+/* google.protobuf.OneofDescriptorProto */
+
+UPB_INLINE google_protobuf_OneofDescriptorProto *google_protobuf_OneofDescriptorProto_new(upb_arena *arena) {
+ return (google_protobuf_OneofDescriptorProto *)upb_msg_new(&google_protobuf_OneofDescriptorProto_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_name(const google_protobuf_OneofDescriptorProto *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE upb_strview google_protobuf_OneofDescriptorProto_name(const google_protobuf_OneofDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); }
+UPB_INLINE bool google_protobuf_OneofDescriptorProto_has_options(const google_protobuf_OneofDescriptorProto *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE const google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_options(const google_protobuf_OneofDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_OneofOptions*, UPB_SIZE(12, 24)); }
+
+UPB_INLINE void google_protobuf_OneofDescriptorProto_set_name(google_protobuf_OneofDescriptorProto *msg, upb_strview value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value;
+}
+UPB_INLINE void google_protobuf_OneofDescriptorProto_set_options(google_protobuf_OneofDescriptorProto *msg, google_protobuf_OneofOptions* value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, google_protobuf_OneofOptions*, UPB_SIZE(12, 24)) = value;
+}
+UPB_INLINE struct google_protobuf_OneofOptions* google_protobuf_OneofDescriptorProto_mutable_options(google_protobuf_OneofDescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_OneofOptions* sub = (struct google_protobuf_OneofOptions*)google_protobuf_OneofDescriptorProto_options(msg);
+ if (sub == NULL) {
+ sub = (struct google_protobuf_OneofOptions*)upb_msg_new(&google_protobuf_OneofOptions_msginit, arena);
+ if (!sub) return NULL;
+ google_protobuf_OneofDescriptorProto_set_options(msg, sub);
+ }
+ return sub;
+}
+
+/* google.protobuf.EnumDescriptorProto */
+
+UPB_INLINE google_protobuf_EnumDescriptorProto *google_protobuf_EnumDescriptorProto_new(upb_arena *arena) {
+ return (google_protobuf_EnumDescriptorProto *)upb_msg_new(&google_protobuf_EnumDescriptorProto_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_name(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE upb_strview google_protobuf_EnumDescriptorProto_name(const google_protobuf_EnumDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); }
+UPB_INLINE const google_protobuf_EnumValueDescriptorProto* const* google_protobuf_EnumDescriptorProto_value(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumValueDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
+UPB_INLINE bool google_protobuf_EnumDescriptorProto_has_options(const google_protobuf_EnumDescriptorProto *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE const google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_options(const google_protobuf_EnumDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_EnumOptions*, UPB_SIZE(12, 24)); }
+UPB_INLINE const google_protobuf_EnumDescriptorProto_EnumReservedRange* const* google_protobuf_EnumDescriptorProto_reserved_range(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (const google_protobuf_EnumDescriptorProto_EnumReservedRange* const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); }
+UPB_INLINE upb_strview const* google_protobuf_EnumDescriptorProto_reserved_name(const google_protobuf_EnumDescriptorProto *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); }
+
+UPB_INLINE void google_protobuf_EnumDescriptorProto_set_name(google_protobuf_EnumDescriptorProto *msg, upb_strview value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value;
+}
+UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescriptorProto_mutable_value(google_protobuf_EnumDescriptorProto *msg, size_t *len) {
+ return (google_protobuf_EnumValueDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
+}
+UPB_INLINE google_protobuf_EnumValueDescriptorProto** google_protobuf_EnumDescriptorProto_resize_value(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_EnumValueDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_EnumValueDescriptorProto* google_protobuf_EnumDescriptorProto_add_value(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_EnumValueDescriptorProto* sub = (struct google_protobuf_EnumValueDescriptorProto*)upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+UPB_INLINE void google_protobuf_EnumDescriptorProto_set_options(google_protobuf_EnumDescriptorProto *msg, google_protobuf_EnumOptions* value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, google_protobuf_EnumOptions*, UPB_SIZE(12, 24)) = value;
+}
+UPB_INLINE struct google_protobuf_EnumOptions* google_protobuf_EnumDescriptorProto_mutable_options(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_EnumOptions* sub = (struct google_protobuf_EnumOptions*)google_protobuf_EnumDescriptorProto_options(msg);
+ if (sub == NULL) {
+ sub = (struct google_protobuf_EnumOptions*)upb_msg_new(&google_protobuf_EnumOptions_msginit, arena);
+ if (!sub) return NULL;
+ google_protobuf_EnumDescriptorProto_set_options(msg, sub);
+ }
+ return sub;
+}
+UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protobuf_EnumDescriptorProto_mutable_reserved_range(google_protobuf_EnumDescriptorProto *msg, size_t *len) {
+ return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
+}
+UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange** google_protobuf_EnumDescriptorProto_resize_reserved_range(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_EnumDescriptorProto_EnumReservedRange**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_EnumDescriptorProto_EnumReservedRange* google_protobuf_EnumDescriptorProto_add_reserved_range(google_protobuf_EnumDescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_EnumDescriptorProto_EnumReservedRange* sub = (struct google_protobuf_EnumDescriptorProto_EnumReservedRange*)upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(20, 40), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_mutable_reserved_name(google_protobuf_EnumDescriptorProto *msg, size_t *len) {
+ return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
+}
+UPB_INLINE upb_strview* google_protobuf_EnumDescriptorProto_resize_reserved_name(google_protobuf_EnumDescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena);
+}
+UPB_INLINE bool google_protobuf_EnumDescriptorProto_add_reserved_name(google_protobuf_EnumDescriptorProto *msg, upb_strview val, upb_arena *arena) {
+ return _upb_array_append_accessor(
+ msg, UPB_SIZE(24, 48), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena);
+}
+
+/* google.protobuf.EnumDescriptorProto.EnumReservedRange */
+
+UPB_INLINE google_protobuf_EnumDescriptorProto_EnumReservedRange *google_protobuf_EnumDescriptorProto_EnumReservedRange_new(upb_arena *arena) {
+ return (google_protobuf_EnumDescriptorProto_EnumReservedRange *)upb_msg_new(&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_start(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); }
+UPB_INLINE bool google_protobuf_EnumDescriptorProto_EnumReservedRange_has_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE int32_t google_protobuf_EnumDescriptorProto_EnumReservedRange_end(const google_protobuf_EnumDescriptorProto_EnumReservedRange *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); }
+
+UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_start(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, int32_t value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value;
+}
+UPB_INLINE void google_protobuf_EnumDescriptorProto_EnumReservedRange_set_end(google_protobuf_EnumDescriptorProto_EnumReservedRange *msg, int32_t value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value;
+}
+
+/* google.protobuf.EnumValueDescriptorProto */
+
+UPB_INLINE google_protobuf_EnumValueDescriptorProto *google_protobuf_EnumValueDescriptorProto_new(upb_arena *arena) {
+ return (google_protobuf_EnumValueDescriptorProto *)upb_msg_new(&google_protobuf_EnumValueDescriptorProto_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_name(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE upb_strview google_protobuf_EnumValueDescriptorProto_name(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)); }
+UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_number(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE int32_t google_protobuf_EnumValueDescriptorProto_number(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); }
+UPB_INLINE bool google_protobuf_EnumValueDescriptorProto_has_options(const google_protobuf_EnumValueDescriptorProto *msg) { return _upb_has_field(msg, 3); }
+UPB_INLINE const google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_options(const google_protobuf_EnumValueDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_EnumValueOptions*, UPB_SIZE(16, 24)); }
+
+UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_name(google_protobuf_EnumValueDescriptorProto *msg, upb_strview value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 8)) = value;
+}
+UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_number(google_protobuf_EnumValueDescriptorProto *msg, int32_t value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value;
+}
+UPB_INLINE void google_protobuf_EnumValueDescriptorProto_set_options(google_protobuf_EnumValueDescriptorProto *msg, google_protobuf_EnumValueOptions* value) {
+ _upb_sethas(msg, 3);
+ UPB_FIELD_AT(msg, google_protobuf_EnumValueOptions*, UPB_SIZE(16, 24)) = value;
+}
+UPB_INLINE struct google_protobuf_EnumValueOptions* google_protobuf_EnumValueDescriptorProto_mutable_options(google_protobuf_EnumValueDescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_EnumValueOptions* sub = (struct google_protobuf_EnumValueOptions*)google_protobuf_EnumValueDescriptorProto_options(msg);
+ if (sub == NULL) {
+ sub = (struct google_protobuf_EnumValueOptions*)upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena);
+ if (!sub) return NULL;
+ google_protobuf_EnumValueDescriptorProto_set_options(msg, sub);
+ }
+ return sub;
+}
+
+/* google.protobuf.ServiceDescriptorProto */
+
+UPB_INLINE google_protobuf_ServiceDescriptorProto *google_protobuf_ServiceDescriptorProto_new(upb_arena *arena) {
+ return (google_protobuf_ServiceDescriptorProto *)upb_msg_new(&google_protobuf_ServiceDescriptorProto_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_name(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE upb_strview google_protobuf_ServiceDescriptorProto_name(const google_protobuf_ServiceDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); }
+UPB_INLINE const google_protobuf_MethodDescriptorProto* const* google_protobuf_ServiceDescriptorProto_method(const google_protobuf_ServiceDescriptorProto *msg, size_t *len) { return (const google_protobuf_MethodDescriptorProto* const*)_upb_array_accessor(msg, UPB_SIZE(16, 32), len); }
+UPB_INLINE bool google_protobuf_ServiceDescriptorProto_has_options(const google_protobuf_ServiceDescriptorProto *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE const google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_options(const google_protobuf_ServiceDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_ServiceOptions*, UPB_SIZE(12, 24)); }
+
+UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_name(google_protobuf_ServiceDescriptorProto *msg, upb_strview value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value;
+}
+UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescriptorProto_mutable_method(google_protobuf_ServiceDescriptorProto *msg, size_t *len) {
+ return (google_protobuf_MethodDescriptorProto**)_upb_array_mutable_accessor(msg, UPB_SIZE(16, 32), len);
+}
+UPB_INLINE google_protobuf_MethodDescriptorProto** google_protobuf_ServiceDescriptorProto_resize_method(google_protobuf_ServiceDescriptorProto *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_MethodDescriptorProto**)_upb_array_resize_accessor(msg, UPB_SIZE(16, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_MethodDescriptorProto* google_protobuf_ServiceDescriptorProto_add_method(google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_MethodDescriptorProto* sub = (struct google_protobuf_MethodDescriptorProto*)upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(16, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+UPB_INLINE void google_protobuf_ServiceDescriptorProto_set_options(google_protobuf_ServiceDescriptorProto *msg, google_protobuf_ServiceOptions* value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, google_protobuf_ServiceOptions*, UPB_SIZE(12, 24)) = value;
+}
+UPB_INLINE struct google_protobuf_ServiceOptions* google_protobuf_ServiceDescriptorProto_mutable_options(google_protobuf_ServiceDescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_ServiceOptions* sub = (struct google_protobuf_ServiceOptions*)google_protobuf_ServiceDescriptorProto_options(msg);
+ if (sub == NULL) {
+ sub = (struct google_protobuf_ServiceOptions*)upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena);
+ if (!sub) return NULL;
+ google_protobuf_ServiceDescriptorProto_set_options(msg, sub);
+ }
+ return sub;
+}
+
+/* google.protobuf.MethodDescriptorProto */
+
+UPB_INLINE google_protobuf_MethodDescriptorProto *google_protobuf_MethodDescriptorProto_new(upb_arena *arena) {
+ return (google_protobuf_MethodDescriptorProto *)upb_msg_new(&google_protobuf_MethodDescriptorProto_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_name(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 3); }
+UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_name(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_input_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 4); }
+UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_input_type(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_output_type(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 5); }
+UPB_INLINE upb_strview google_protobuf_MethodDescriptorProto_output_type(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_options(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 6); }
+UPB_INLINE const google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_options(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, const google_protobuf_MethodOptions*, UPB_SIZE(28, 56)); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_client_streaming(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_has_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE bool google_protobuf_MethodDescriptorProto_server_streaming(const google_protobuf_MethodDescriptorProto *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); }
+
+UPB_INLINE void google_protobuf_MethodDescriptorProto_set_name(google_protobuf_MethodDescriptorProto *msg, upb_strview value) {
+ _upb_sethas(msg, 3);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value;
+}
+UPB_INLINE void google_protobuf_MethodDescriptorProto_set_input_type(google_protobuf_MethodDescriptorProto *msg, upb_strview value) {
+ _upb_sethas(msg, 4);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)) = value;
+}
+UPB_INLINE void google_protobuf_MethodDescriptorProto_set_output_type(google_protobuf_MethodDescriptorProto *msg, upb_strview value) {
+ _upb_sethas(msg, 5);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(20, 40)) = value;
+}
+UPB_INLINE void google_protobuf_MethodDescriptorProto_set_options(google_protobuf_MethodDescriptorProto *msg, google_protobuf_MethodOptions* value) {
+ _upb_sethas(msg, 6);
+ UPB_FIELD_AT(msg, google_protobuf_MethodOptions*, UPB_SIZE(28, 56)) = value;
+}
+UPB_INLINE struct google_protobuf_MethodOptions* google_protobuf_MethodDescriptorProto_mutable_options(google_protobuf_MethodDescriptorProto *msg, upb_arena *arena) {
+ struct google_protobuf_MethodOptions* sub = (struct google_protobuf_MethodOptions*)google_protobuf_MethodDescriptorProto_options(msg);
+ if (sub == NULL) {
+ sub = (struct google_protobuf_MethodOptions*)upb_msg_new(&google_protobuf_MethodOptions_msginit, arena);
+ if (!sub) return NULL;
+ google_protobuf_MethodDescriptorProto_set_options(msg, sub);
+ }
+ return sub;
+}
+UPB_INLINE void google_protobuf_MethodDescriptorProto_set_client_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value;
+}
+UPB_INLINE void google_protobuf_MethodDescriptorProto_set_server_streaming(google_protobuf_MethodDescriptorProto *msg, bool value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value;
+}
+
+/* google.protobuf.FileOptions */
+
+UPB_INLINE google_protobuf_FileOptions *google_protobuf_FileOptions_new(upb_arena *arena) {
+ return (google_protobuf_FileOptions *)upb_msg_new(&google_protobuf_FileOptions_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_FileOptions_has_java_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 11); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_java_package(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(28, 32)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_outer_classname(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 12); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_java_outer_classname(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(36, 48)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_optimize_for(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE int32_t google_protobuf_FileOptions_optimize_for(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_multiple_files(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE bool google_protobuf_FileOptions_java_multiple_files(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_go_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 13); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_go_package(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(44, 64)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_cc_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 3); }
+UPB_INLINE bool google_protobuf_FileOptions_cc_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(17, 17)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 4); }
+UPB_INLINE bool google_protobuf_FileOptions_java_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_py_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 5); }
+UPB_INLINE bool google_protobuf_FileOptions_py_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(19, 19)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 6); }
+UPB_INLINE bool google_protobuf_FileOptions_java_generate_equals_and_hash(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(20, 20)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_deprecated(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 7); }
+UPB_INLINE bool google_protobuf_FileOptions_deprecated(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 8); }
+UPB_INLINE bool google_protobuf_FileOptions_java_string_check_utf8(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(22, 22)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 9); }
+UPB_INLINE bool google_protobuf_FileOptions_cc_enable_arenas(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_objc_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 14); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_objc_class_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(52, 80)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_csharp_namespace(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 15); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_csharp_namespace(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(60, 96)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_swift_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 16); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_swift_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(68, 112)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_php_class_prefix(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 17); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_php_class_prefix(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(76, 128)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_php_namespace(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 18); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_php_namespace(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(84, 144)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_php_generic_services(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 10); }
+UPB_INLINE bool google_protobuf_FileOptions_php_generic_services(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 19); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_php_metadata_namespace(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(92, 160)); }
+UPB_INLINE bool google_protobuf_FileOptions_has_ruby_package(const google_protobuf_FileOptions *msg) { return _upb_has_field(msg, 20); }
+UPB_INLINE upb_strview google_protobuf_FileOptions_ruby_package(const google_protobuf_FileOptions *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(100, 176)); }
+UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FileOptions_uninterpreted_option(const google_protobuf_FileOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(108, 192), len); }
+
+UPB_INLINE void google_protobuf_FileOptions_set_java_package(google_protobuf_FileOptions *msg, upb_strview value) {
+ _upb_sethas(msg, 11);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(28, 32)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_java_outer_classname(google_protobuf_FileOptions *msg, upb_strview value) {
+ _upb_sethas(msg, 12);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(36, 48)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_optimize_for(google_protobuf_FileOptions *msg, int32_t value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_java_multiple_files(google_protobuf_FileOptions *msg, bool value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_go_package(google_protobuf_FileOptions *msg, upb_strview value) {
+ _upb_sethas(msg, 13);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(44, 64)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_cc_generic_services(google_protobuf_FileOptions *msg, bool value) {
+ _upb_sethas(msg, 3);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(17, 17)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_java_generic_services(google_protobuf_FileOptions *msg, bool value) {
+ _upb_sethas(msg, 4);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(18, 18)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_py_generic_services(google_protobuf_FileOptions *msg, bool value) {
+ _upb_sethas(msg, 5);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(19, 19)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_java_generate_equals_and_hash(google_protobuf_FileOptions *msg, bool value) {
+ _upb_sethas(msg, 6);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(20, 20)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_deprecated(google_protobuf_FileOptions *msg, bool value) {
+ _upb_sethas(msg, 7);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(21, 21)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_java_string_check_utf8(google_protobuf_FileOptions *msg, bool value) {
+ _upb_sethas(msg, 8);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(22, 22)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_cc_enable_arenas(google_protobuf_FileOptions *msg, bool value) {
+ _upb_sethas(msg, 9);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(23, 23)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_objc_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) {
+ _upb_sethas(msg, 14);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(52, 80)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_csharp_namespace(google_protobuf_FileOptions *msg, upb_strview value) {
+ _upb_sethas(msg, 15);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(60, 96)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_swift_prefix(google_protobuf_FileOptions *msg, upb_strview value) {
+ _upb_sethas(msg, 16);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(68, 112)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_php_class_prefix(google_protobuf_FileOptions *msg, upb_strview value) {
+ _upb_sethas(msg, 17);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(76, 128)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_php_namespace(google_protobuf_FileOptions *msg, upb_strview value) {
+ _upb_sethas(msg, 18);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(84, 144)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_php_generic_services(google_protobuf_FileOptions *msg, bool value) {
+ _upb_sethas(msg, 10);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_php_metadata_namespace(google_protobuf_FileOptions *msg, upb_strview value) {
+ _upb_sethas(msg, 19);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(92, 160)) = value;
+}
+UPB_INLINE void google_protobuf_FileOptions_set_ruby_package(google_protobuf_FileOptions *msg, upb_strview value) {
+ _upb_sethas(msg, 20);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(100, 176)) = value;
+}
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_mutable_uninterpreted_option(google_protobuf_FileOptions *msg, size_t *len) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(108, 192), len);
+}
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FileOptions_resize_uninterpreted_option(google_protobuf_FileOptions *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(108, 192), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FileOptions_add_uninterpreted_option(google_protobuf_FileOptions *msg, upb_arena *arena) {
+ struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(108, 192), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+
+/* google.protobuf.MessageOptions */
+
+UPB_INLINE google_protobuf_MessageOptions *google_protobuf_MessageOptions_new(upb_arena *arena) {
+ return (google_protobuf_MessageOptions *)upb_msg_new(&google_protobuf_MessageOptions_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_MessageOptions_has_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE bool google_protobuf_MessageOptions_message_set_wire_format(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); }
+UPB_INLINE bool google_protobuf_MessageOptions_has_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE bool google_protobuf_MessageOptions_no_standard_descriptor_accessor(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); }
+UPB_INLINE bool google_protobuf_MessageOptions_has_deprecated(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 3); }
+UPB_INLINE bool google_protobuf_MessageOptions_deprecated(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)); }
+UPB_INLINE bool google_protobuf_MessageOptions_has_map_entry(const google_protobuf_MessageOptions *msg) { return _upb_has_field(msg, 4); }
+UPB_INLINE bool google_protobuf_MessageOptions_map_entry(const google_protobuf_MessageOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)); }
+UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MessageOptions_uninterpreted_option(const google_protobuf_MessageOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(8, 8), len); }
+
+UPB_INLINE void google_protobuf_MessageOptions_set_message_set_wire_format(google_protobuf_MessageOptions *msg, bool value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value;
+}
+UPB_INLINE void google_protobuf_MessageOptions_set_no_standard_descriptor_accessor(google_protobuf_MessageOptions *msg, bool value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value;
+}
+UPB_INLINE void google_protobuf_MessageOptions_set_deprecated(google_protobuf_MessageOptions *msg, bool value) {
+ _upb_sethas(msg, 3);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(3, 3)) = value;
+}
+UPB_INLINE void google_protobuf_MessageOptions_set_map_entry(google_protobuf_MessageOptions *msg, bool value) {
+ _upb_sethas(msg, 4);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(4, 4)) = value;
+}
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_mutable_uninterpreted_option(google_protobuf_MessageOptions *msg, size_t *len) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 8), len);
+}
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MessageOptions_resize_uninterpreted_option(google_protobuf_MessageOptions *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(8, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MessageOptions_add_uninterpreted_option(google_protobuf_MessageOptions *msg, upb_arena *arena) {
+ struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(8, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+
+/* google.protobuf.FieldOptions */
+
+UPB_INLINE google_protobuf_FieldOptions *google_protobuf_FieldOptions_new(upb_arena *arena) {
+ return (google_protobuf_FieldOptions *)upb_msg_new(&google_protobuf_FieldOptions_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_FieldOptions_has_ctype(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE int32_t google_protobuf_FieldOptions_ctype(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_packed(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 3); }
+UPB_INLINE bool google_protobuf_FieldOptions_packed(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_deprecated(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 4); }
+UPB_INLINE bool google_protobuf_FieldOptions_deprecated(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(25, 25)); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_lazy(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 5); }
+UPB_INLINE bool google_protobuf_FieldOptions_lazy(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_jstype(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE int32_t google_protobuf_FieldOptions_jstype(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)); }
+UPB_INLINE bool google_protobuf_FieldOptions_has_weak(const google_protobuf_FieldOptions *msg) { return _upb_has_field(msg, 6); }
+UPB_INLINE bool google_protobuf_FieldOptions_weak(const google_protobuf_FieldOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)); }
+UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_FieldOptions_uninterpreted_option(const google_protobuf_FieldOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(28, 32), len); }
+
+UPB_INLINE void google_protobuf_FieldOptions_set_ctype(google_protobuf_FieldOptions *msg, int32_t value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value;
+}
+UPB_INLINE void google_protobuf_FieldOptions_set_packed(google_protobuf_FieldOptions *msg, bool value) {
+ _upb_sethas(msg, 3);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(24, 24)) = value;
+}
+UPB_INLINE void google_protobuf_FieldOptions_set_deprecated(google_protobuf_FieldOptions *msg, bool value) {
+ _upb_sethas(msg, 4);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(25, 25)) = value;
+}
+UPB_INLINE void google_protobuf_FieldOptions_set_lazy(google_protobuf_FieldOptions *msg, bool value) {
+ _upb_sethas(msg, 5);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(26, 26)) = value;
+}
+UPB_INLINE void google_protobuf_FieldOptions_set_jstype(google_protobuf_FieldOptions *msg, int32_t value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(16, 16)) = value;
+}
+UPB_INLINE void google_protobuf_FieldOptions_set_weak(google_protobuf_FieldOptions *msg, bool value) {
+ _upb_sethas(msg, 6);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(27, 27)) = value;
+}
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_mutable_uninterpreted_option(google_protobuf_FieldOptions *msg, size_t *len) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 32), len);
+}
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_FieldOptions_resize_uninterpreted_option(google_protobuf_FieldOptions *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(28, 32), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_FieldOptions_add_uninterpreted_option(google_protobuf_FieldOptions *msg, upb_arena *arena) {
+ struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(28, 32), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+
+/* google.protobuf.OneofOptions */
+
+UPB_INLINE google_protobuf_OneofOptions *google_protobuf_OneofOptions_new(upb_arena *arena) {
+ return (google_protobuf_OneofOptions *)upb_msg_new(&google_protobuf_OneofOptions_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_OneofOptions_uninterpreted_option(const google_protobuf_OneofOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); }
+
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_mutable_uninterpreted_option(google_protobuf_OneofOptions *msg, size_t *len) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
+}
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_OneofOptions_resize_uninterpreted_option(google_protobuf_OneofOptions *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_OneofOptions_add_uninterpreted_option(google_protobuf_OneofOptions *msg, upb_arena *arena) {
+ struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+
+/* google.protobuf.EnumOptions */
+
+UPB_INLINE google_protobuf_EnumOptions *google_protobuf_EnumOptions_new(upb_arena *arena) {
+ return (google_protobuf_EnumOptions *)upb_msg_new(&google_protobuf_EnumOptions_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_EnumOptions_has_allow_alias(const google_protobuf_EnumOptions *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE bool google_protobuf_EnumOptions_allow_alias(const google_protobuf_EnumOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); }
+UPB_INLINE bool google_protobuf_EnumOptions_has_deprecated(const google_protobuf_EnumOptions *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE bool google_protobuf_EnumOptions_deprecated(const google_protobuf_EnumOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)); }
+UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumOptions_uninterpreted_option(const google_protobuf_EnumOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); }
+
+UPB_INLINE void google_protobuf_EnumOptions_set_allow_alias(google_protobuf_EnumOptions *msg, bool value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value;
+}
+UPB_INLINE void google_protobuf_EnumOptions_set_deprecated(google_protobuf_EnumOptions *msg, bool value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(2, 2)) = value;
+}
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_mutable_uninterpreted_option(google_protobuf_EnumOptions *msg, size_t *len) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
+}
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumOptions_resize_uninterpreted_option(google_protobuf_EnumOptions *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumOptions_add_uninterpreted_option(google_protobuf_EnumOptions *msg, upb_arena *arena) {
+ struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+
+/* google.protobuf.EnumValueOptions */
+
+UPB_INLINE google_protobuf_EnumValueOptions *google_protobuf_EnumValueOptions_new(upb_arena *arena) {
+ return (google_protobuf_EnumValueOptions *)upb_msg_new(&google_protobuf_EnumValueOptions_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_EnumValueOptions_has_deprecated(const google_protobuf_EnumValueOptions *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE bool google_protobuf_EnumValueOptions_deprecated(const google_protobuf_EnumValueOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); }
+UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_EnumValueOptions_uninterpreted_option(const google_protobuf_EnumValueOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); }
+
+UPB_INLINE void google_protobuf_EnumValueOptions_set_deprecated(google_protobuf_EnumValueOptions *msg, bool value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value;
+}
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_mutable_uninterpreted_option(google_protobuf_EnumValueOptions *msg, size_t *len) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
+}
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_EnumValueOptions_resize_uninterpreted_option(google_protobuf_EnumValueOptions *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_EnumValueOptions_add_uninterpreted_option(google_protobuf_EnumValueOptions *msg, upb_arena *arena) {
+ struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+
+/* google.protobuf.ServiceOptions */
+
+UPB_INLINE google_protobuf_ServiceOptions *google_protobuf_ServiceOptions_new(upb_arena *arena) {
+ return (google_protobuf_ServiceOptions *)upb_msg_new(&google_protobuf_ServiceOptions_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_ServiceOptions_has_deprecated(const google_protobuf_ServiceOptions *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE bool google_protobuf_ServiceOptions_deprecated(const google_protobuf_ServiceOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); }
+UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_ServiceOptions_uninterpreted_option(const google_protobuf_ServiceOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); }
+
+UPB_INLINE void google_protobuf_ServiceOptions_set_deprecated(google_protobuf_ServiceOptions *msg, bool value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value;
+}
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_mutable_uninterpreted_option(google_protobuf_ServiceOptions *msg, size_t *len) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
+}
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_ServiceOptions_resize_uninterpreted_option(google_protobuf_ServiceOptions *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(4, 8), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_ServiceOptions_add_uninterpreted_option(google_protobuf_ServiceOptions *msg, upb_arena *arena) {
+ struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(4, 8), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+
+/* google.protobuf.MethodOptions */
+
+UPB_INLINE google_protobuf_MethodOptions *google_protobuf_MethodOptions_new(upb_arena *arena) {
+ return (google_protobuf_MethodOptions *)upb_msg_new(&google_protobuf_MethodOptions_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_MethodOptions_has_deprecated(const google_protobuf_MethodOptions *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE bool google_protobuf_MethodOptions_deprecated(const google_protobuf_MethodOptions *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)); }
+UPB_INLINE bool google_protobuf_MethodOptions_has_idempotency_level(const google_protobuf_MethodOptions *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE int32_t google_protobuf_MethodOptions_idempotency_level(const google_protobuf_MethodOptions *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); }
+UPB_INLINE const google_protobuf_UninterpretedOption* const* google_protobuf_MethodOptions_uninterpreted_option(const google_protobuf_MethodOptions *msg, size_t *len) { return (const google_protobuf_UninterpretedOption* const*)_upb_array_accessor(msg, UPB_SIZE(20, 24), len); }
+
+UPB_INLINE void google_protobuf_MethodOptions_set_deprecated(google_protobuf_MethodOptions *msg, bool value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(16, 16)) = value;
+}
+UPB_INLINE void google_protobuf_MethodOptions_set_idempotency_level(google_protobuf_MethodOptions *msg, int32_t value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value;
+}
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_mutable_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t *len) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 24), len);
+}
+UPB_INLINE google_protobuf_UninterpretedOption** google_protobuf_MethodOptions_resize_uninterpreted_option(google_protobuf_MethodOptions *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_UninterpretedOption**)_upb_array_resize_accessor(msg, UPB_SIZE(20, 24), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_UninterpretedOption* google_protobuf_MethodOptions_add_uninterpreted_option(google_protobuf_MethodOptions *msg, upb_arena *arena) {
+ struct google_protobuf_UninterpretedOption* sub = (struct google_protobuf_UninterpretedOption*)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(20, 24), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+
+/* google.protobuf.UninterpretedOption */
+
+UPB_INLINE google_protobuf_UninterpretedOption *google_protobuf_UninterpretedOption_new(upb_arena *arena) {
+ return (google_protobuf_UninterpretedOption *)upb_msg_new(&google_protobuf_UninterpretedOption_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE const google_protobuf_UninterpretedOption_NamePart* const* google_protobuf_UninterpretedOption_name(const google_protobuf_UninterpretedOption *msg, size_t *len) { return (const google_protobuf_UninterpretedOption_NamePart* const*)_upb_array_accessor(msg, UPB_SIZE(56, 80), len); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_identifier_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 4); }
+UPB_INLINE upb_strview google_protobuf_UninterpretedOption_identifier_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE uint64_t google_protobuf_UninterpretedOption_positive_int_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE int64_t google_protobuf_UninterpretedOption_negative_int_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_double_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 3); }
+UPB_INLINE double google_protobuf_UninterpretedOption_double_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_string_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 5); }
+UPB_INLINE upb_strview google_protobuf_UninterpretedOption_string_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_has_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return _upb_has_field(msg, 6); }
+UPB_INLINE upb_strview google_protobuf_UninterpretedOption_aggregate_value(const google_protobuf_UninterpretedOption *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)); }
+
+UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_mutable_name(google_protobuf_UninterpretedOption *msg, size_t *len) {
+ return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_mutable_accessor(msg, UPB_SIZE(56, 80), len);
+}
+UPB_INLINE google_protobuf_UninterpretedOption_NamePart** google_protobuf_UninterpretedOption_resize_name(google_protobuf_UninterpretedOption *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_UninterpretedOption_NamePart**)_upb_array_resize_accessor(msg, UPB_SIZE(56, 80), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_UninterpretedOption_NamePart* google_protobuf_UninterpretedOption_add_name(google_protobuf_UninterpretedOption *msg, upb_arena *arena) {
+ struct google_protobuf_UninterpretedOption_NamePart* sub = (struct google_protobuf_UninterpretedOption_NamePart*)upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(56, 80), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+UPB_INLINE void google_protobuf_UninterpretedOption_set_identifier_value(google_protobuf_UninterpretedOption *msg, upb_strview value) {
+ _upb_sethas(msg, 4);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(32, 32)) = value;
+}
+UPB_INLINE void google_protobuf_UninterpretedOption_set_positive_int_value(google_protobuf_UninterpretedOption *msg, uint64_t value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(8, 8)) = value;
+}
+UPB_INLINE void google_protobuf_UninterpretedOption_set_negative_int_value(google_protobuf_UninterpretedOption *msg, int64_t value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, int64_t, UPB_SIZE(16, 16)) = value;
+}
+UPB_INLINE void google_protobuf_UninterpretedOption_set_double_value(google_protobuf_UninterpretedOption *msg, double value) {
+ _upb_sethas(msg, 3);
+ UPB_FIELD_AT(msg, double, UPB_SIZE(24, 24)) = value;
+}
+UPB_INLINE void google_protobuf_UninterpretedOption_set_string_value(google_protobuf_UninterpretedOption *msg, upb_strview value) {
+ _upb_sethas(msg, 5);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(40, 48)) = value;
+}
+UPB_INLINE void google_protobuf_UninterpretedOption_set_aggregate_value(google_protobuf_UninterpretedOption *msg, upb_strview value) {
+ _upb_sethas(msg, 6);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(48, 64)) = value;
+}
+
+/* google.protobuf.UninterpretedOption.NamePart */
+
+UPB_INLINE google_protobuf_UninterpretedOption_NamePart *google_protobuf_UninterpretedOption_NamePart_new(upb_arena *arena) {
+ return (google_protobuf_UninterpretedOption_NamePart *)upb_msg_new(&google_protobuf_UninterpretedOption_NamePart_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE upb_strview google_protobuf_UninterpretedOption_NamePart_name_part(const google_protobuf_UninterpretedOption_NamePart *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_has_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE bool google_protobuf_UninterpretedOption_NamePart_is_extension(const google_protobuf_UninterpretedOption_NamePart *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)); }
+
+UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_name_part(google_protobuf_UninterpretedOption_NamePart *msg, upb_strview value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value;
+}
+UPB_INLINE void google_protobuf_UninterpretedOption_NamePart_set_is_extension(google_protobuf_UninterpretedOption_NamePart *msg, bool value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, bool, UPB_SIZE(1, 1)) = value;
+}
+
+/* google.protobuf.SourceCodeInfo */
+
+UPB_INLINE google_protobuf_SourceCodeInfo *google_protobuf_SourceCodeInfo_new(upb_arena *arena) {
+ return (google_protobuf_SourceCodeInfo *)upb_msg_new(&google_protobuf_SourceCodeInfo_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE const google_protobuf_SourceCodeInfo_Location* const* google_protobuf_SourceCodeInfo_location(const google_protobuf_SourceCodeInfo *msg, size_t *len) { return (const google_protobuf_SourceCodeInfo_Location* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); }
+
+UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeInfo_mutable_location(google_protobuf_SourceCodeInfo *msg, size_t *len) {
+ return (google_protobuf_SourceCodeInfo_Location**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
+}
+UPB_INLINE google_protobuf_SourceCodeInfo_Location** google_protobuf_SourceCodeInfo_resize_location(google_protobuf_SourceCodeInfo *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_SourceCodeInfo_Location**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_SourceCodeInfo_Location* google_protobuf_SourceCodeInfo_add_location(google_protobuf_SourceCodeInfo *msg, upb_arena *arena) {
+ struct google_protobuf_SourceCodeInfo_Location* sub = (struct google_protobuf_SourceCodeInfo_Location*)upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+
+/* google.protobuf.SourceCodeInfo.Location */
+
+UPB_INLINE google_protobuf_SourceCodeInfo_Location *google_protobuf_SourceCodeInfo_Location_new(upb_arena *arena) {
+ return (google_protobuf_SourceCodeInfo_Location *)upb_msg_new(&google_protobuf_SourceCodeInfo_Location_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE int32_t const* google_protobuf_SourceCodeInfo_Location_path(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(20, 40), len); }
+UPB_INLINE int32_t const* google_protobuf_SourceCodeInfo_Location_span(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(24, 48), len); }
+UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE upb_strview google_protobuf_SourceCodeInfo_Location_leading_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)); }
+UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_has_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE upb_strview google_protobuf_SourceCodeInfo_Location_trailing_comments(const google_protobuf_SourceCodeInfo_Location *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)); }
+UPB_INLINE upb_strview const* google_protobuf_SourceCodeInfo_Location_leading_detached_comments(const google_protobuf_SourceCodeInfo_Location *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(28, 56), len); }
+
+UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_path(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) {
+ return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 40), len);
+}
+UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_path(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) {
+ return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 40), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena);
+}
+UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_path(google_protobuf_SourceCodeInfo_Location *msg, int32_t val, upb_arena *arena) {
+ return _upb_array_append_accessor(
+ msg, UPB_SIZE(20, 40), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena);
+}
+UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_mutable_span(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) {
+ return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(24, 48), len);
+}
+UPB_INLINE int32_t* google_protobuf_SourceCodeInfo_Location_resize_span(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) {
+ return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(24, 48), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena);
+}
+UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_span(google_protobuf_SourceCodeInfo_Location *msg, int32_t val, upb_arena *arena) {
+ return _upb_array_append_accessor(
+ msg, UPB_SIZE(24, 48), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena);
+}
+UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_leading_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(4, 8)) = value;
+}
+UPB_INLINE void google_protobuf_SourceCodeInfo_Location_set_trailing_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 24)) = value;
+}
+UPB_INLINE upb_strview* google_protobuf_SourceCodeInfo_Location_mutable_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, size_t *len) {
+ return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(28, 56), len);
+}
+UPB_INLINE upb_strview* google_protobuf_SourceCodeInfo_Location_resize_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, size_t len, upb_arena *arena) {
+ return (upb_strview*)_upb_array_resize_accessor(msg, UPB_SIZE(28, 56), len, UPB_SIZE(8, 16), UPB_TYPE_STRING, arena);
+}
+UPB_INLINE bool google_protobuf_SourceCodeInfo_Location_add_leading_detached_comments(google_protobuf_SourceCodeInfo_Location *msg, upb_strview val, upb_arena *arena) {
+ return _upb_array_append_accessor(
+ msg, UPB_SIZE(28, 56), UPB_SIZE(8, 16), UPB_TYPE_STRING, &val, arena);
+}
+
+/* google.protobuf.GeneratedCodeInfo */
+
+UPB_INLINE google_protobuf_GeneratedCodeInfo *google_protobuf_GeneratedCodeInfo_new(upb_arena *arena) {
+ return (google_protobuf_GeneratedCodeInfo *)upb_msg_new(&google_protobuf_GeneratedCodeInfo_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE const google_protobuf_GeneratedCodeInfo_Annotation* const* google_protobuf_GeneratedCodeInfo_annotation(const google_protobuf_GeneratedCodeInfo *msg, size_t *len) { return (const google_protobuf_GeneratedCodeInfo_Annotation* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); }
+
+UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_GeneratedCodeInfo_mutable_annotation(google_protobuf_GeneratedCodeInfo *msg, size_t *len) {
+ return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
+}
+UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation** google_protobuf_GeneratedCodeInfo_resize_annotation(google_protobuf_GeneratedCodeInfo *msg, size_t len, upb_arena *arena) {
+ return (google_protobuf_GeneratedCodeInfo_Annotation**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena);
+}
+UPB_INLINE struct google_protobuf_GeneratedCodeInfo_Annotation* google_protobuf_GeneratedCodeInfo_add_annotation(google_protobuf_GeneratedCodeInfo *msg, upb_arena *arena) {
+ struct google_protobuf_GeneratedCodeInfo_Annotation* sub = (struct google_protobuf_GeneratedCodeInfo_Annotation*)upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena);
+ bool ok = _upb_array_append_accessor(
+ msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena);
+ if (!ok) return NULL;
+ return sub;
+}
+
+/* google.protobuf.GeneratedCodeInfo.Annotation */
+
+UPB_INLINE google_protobuf_GeneratedCodeInfo_Annotation *google_protobuf_GeneratedCodeInfo_Annotation_new(upb_arena *arena) {
+ return (google_protobuf_GeneratedCodeInfo_Annotation *)upb_msg_new(&google_protobuf_GeneratedCodeInfo_Annotation_msginit, arena);
+}
+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;
+}
+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);
+}
+
+UPB_INLINE int32_t const* google_protobuf_GeneratedCodeInfo_Annotation_path(const google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t *len) { return (int32_t const*)_upb_array_accessor(msg, UPB_SIZE(20, 32), len); }
+UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 3); }
+UPB_INLINE upb_strview google_protobuf_GeneratedCodeInfo_Annotation_source_file(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 16)); }
+UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 1); }
+UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_begin(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)); }
+UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_has_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return _upb_has_field(msg, 2); }
+UPB_INLINE int32_t google_protobuf_GeneratedCodeInfo_Annotation_end(const google_protobuf_GeneratedCodeInfo_Annotation *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); }
+
+UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_mutable_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t *len) {
+ return (int32_t*)_upb_array_mutable_accessor(msg, UPB_SIZE(20, 32), len);
+}
+UPB_INLINE int32_t* google_protobuf_GeneratedCodeInfo_Annotation_resize_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, size_t len, upb_arena *arena) {
+ return (int32_t*)_upb_array_resize_accessor(msg, UPB_SIZE(20, 32), len, UPB_SIZE(4, 4), UPB_TYPE_INT32, arena);
+}
+UPB_INLINE bool google_protobuf_GeneratedCodeInfo_Annotation_add_path(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t val, upb_arena *arena) {
+ return _upb_array_append_accessor(
+ msg, UPB_SIZE(20, 32), UPB_SIZE(4, 4), UPB_TYPE_INT32, &val, arena);
+}
+UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_source_file(google_protobuf_GeneratedCodeInfo_Annotation *msg, upb_strview value) {
+ _upb_sethas(msg, 3);
+ UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(12, 16)) = value;
+}
+UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_begin(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) {
+ _upb_sethas(msg, 1);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(4, 4)) = value;
+}
+UPB_INLINE void google_protobuf_GeneratedCodeInfo_Annotation_set_end(google_protobuf_GeneratedCodeInfo_Annotation *msg, int32_t value) {
+ _upb_sethas(msg, 2);
+ UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value;
+}
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#include "upb/port_undef.inc"
+
+#endif /* GOOGLE_PROTOBUF_DESCRIPTOR_PROTO_UPB_H_ */
diff --git a/third_party/upb/generated_for_cmake/upb/json/parser.c b/third_party/upb/generated_for_cmake/upb/json/parser.c
new file mode 100644
index 00000000000..f72e945881f
--- /dev/null
+++ b/third_party/upb/generated_for_cmake/upb/json/parser.c
@@ -0,0 +1,3454 @@
+
+#line 1 "upb/json/parser.rl"
+/*
+** upb::json::Parser (upb_json_parser)
+**
+** A parser that uses the Ragel State Machine Compiler to generate
+** the finite automata.
+**
+** Ragel only natively handles regular languages, but we can manually
+** program it a bit to handle context-free languages like JSON, by using
+** the "fcall" and "fret" constructs.
+**
+** This parser can handle the basics, but needs several things to be fleshed
+** out:
+**
+** - handling of unicode escape sequences (including high surrogate pairs).
+** - properly check and report errors for unknown fields, stack overflow,
+** improper array nesting (or lack of nesting).
+** - handling of base64 sequences with padding characters.
+** - handling of push-back (non-success returns from sink functions).
+** - handling of keys/escape-sequences/etc that span input buffers.
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include "upb/json/parser.h"
+#include "upb/pb/encoder.h"
+
+#include "upb/port_def.inc"
+
+#define UPB_JSON_MAX_DEPTH 64
+
+/* Type of value message */
+enum {
+ VALUE_NULLVALUE = 0,
+ VALUE_NUMBERVALUE = 1,
+ VALUE_STRINGVALUE = 2,
+ VALUE_BOOLVALUE = 3,
+ VALUE_STRUCTVALUE = 4,
+ VALUE_LISTVALUE = 5
+};
+
+/* Forward declare */
+static bool is_top_level(upb_json_parser *p);
+static bool is_wellknown_msg(upb_json_parser *p, upb_wellknowntype_t type);
+static bool is_wellknown_field(upb_json_parser *p, upb_wellknowntype_t type);
+
+static bool is_number_wrapper_object(upb_json_parser *p);
+static bool does_number_wrapper_start(upb_json_parser *p);
+static bool does_number_wrapper_end(upb_json_parser *p);
+
+static bool is_string_wrapper_object(upb_json_parser *p);
+static bool does_string_wrapper_start(upb_json_parser *p);
+static bool does_string_wrapper_end(upb_json_parser *p);
+
+static bool does_fieldmask_start(upb_json_parser *p);
+static bool does_fieldmask_end(upb_json_parser *p);
+static void start_fieldmask_object(upb_json_parser *p);
+static void end_fieldmask_object(upb_json_parser *p);
+
+static void start_wrapper_object(upb_json_parser *p);
+static void end_wrapper_object(upb_json_parser *p);
+
+static void start_value_object(upb_json_parser *p, int value_type);
+static void end_value_object(upb_json_parser *p);
+
+static void start_listvalue_object(upb_json_parser *p);
+static void end_listvalue_object(upb_json_parser *p);
+
+static void start_structvalue_object(upb_json_parser *p);
+static void end_structvalue_object(upb_json_parser *p);
+
+static void start_object(upb_json_parser *p);
+static void end_object(upb_json_parser *p);
+
+static void start_any_object(upb_json_parser *p, const char *ptr);
+static bool end_any_object(upb_json_parser *p, const char *ptr);
+
+static bool start_subobject(upb_json_parser *p);
+static void end_subobject(upb_json_parser *p);
+
+static void start_member(upb_json_parser *p);
+static void end_member(upb_json_parser *p);
+static bool end_membername(upb_json_parser *p);
+
+static void start_any_member(upb_json_parser *p, const char *ptr);
+static void end_any_member(upb_json_parser *p, const char *ptr);
+static bool end_any_membername(upb_json_parser *p);
+
+size_t parse(void *closure, const void *hd, const char *buf, size_t size,
+ const upb_bufhandle *handle);
+static bool end(void *closure, const void *hd);
+
+static const char eof_ch = 'e';
+
+/* stringsink */
+typedef struct {
+ upb_byteshandler handler;
+ upb_bytessink sink;
+ char *ptr;
+ size_t len, size;
+} upb_stringsink;
+
+
+static void *stringsink_start(void *_sink, const void *hd, size_t size_hint) {
+ upb_stringsink *sink = _sink;
+ sink->len = 0;
+ UPB_UNUSED(hd);
+ UPB_UNUSED(size_hint);
+ return sink;
+}
+
+static size_t stringsink_string(void *_sink, const void *hd, const char *ptr,
+ size_t len, const upb_bufhandle *handle) {
+ upb_stringsink *sink = _sink;
+ size_t new_size = sink->size;
+
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+
+ while (sink->len + len > new_size) {
+ new_size *= 2;
+ }
+
+ if (new_size != sink->size) {
+ sink->ptr = realloc(sink->ptr, new_size);
+ sink->size = new_size;
+ }
+
+ memcpy(sink->ptr + sink->len, ptr, len);
+ sink->len += len;
+
+ return len;
+}
+
+void upb_stringsink_init(upb_stringsink *sink) {
+ upb_byteshandler_init(&sink->handler);
+ upb_byteshandler_setstartstr(&sink->handler, stringsink_start, NULL);
+ upb_byteshandler_setstring(&sink->handler, stringsink_string, NULL);
+
+ upb_bytessink_reset(&sink->sink, &sink->handler, sink);
+
+ sink->size = 32;
+ sink->ptr = malloc(sink->size);
+ sink->len = 0;
+}
+
+void upb_stringsink_uninit(upb_stringsink *sink) { free(sink->ptr); }
+
+typedef struct {
+ /* For encoding Any value field in binary format. */
+ upb_handlercache *encoder_handlercache;
+ upb_stringsink stringsink;
+
+ /* For decoding Any value field in json format. */
+ upb_json_codecache *parser_codecache;
+ upb_sink sink;
+ upb_json_parser *parser;
+
+ /* Mark the range of uninterpreted values in json input before type url. */
+ const char *before_type_url_start;
+ const char *before_type_url_end;
+
+ /* Mark the range of uninterpreted values in json input after type url. */
+ const char *after_type_url_start;
+} upb_jsonparser_any_frame;
+
+typedef struct {
+ upb_sink sink;
+
+ /* The current message in which we're parsing, and the field whose value we're
+ * expecting next. */
+ const upb_msgdef *m;
+ const upb_fielddef *f;
+
+ /* The table mapping json name to fielddef for this message. */
+ const upb_strtable *name_table;
+
+ /* We are in a repeated-field context. We need this flag to decide whether to
+ * handle the array as a normal repeated field or a
+ * google.protobuf.ListValue/google.protobuf.Value. */
+ bool is_repeated;
+
+ /* We are in a repeated-field context, ready to emit mapentries as
+ * submessages. This flag alters the start-of-object (open-brace) behavior to
+ * begin a sequence of mapentry messages rather than a single submessage. */
+ bool is_map;
+
+ /* We are in a map-entry message context. This flag is set when parsing the
+ * value field of a single map entry and indicates to all value-field parsers
+ * (subobjects, strings, numbers, and bools) that the map-entry submessage
+ * should end as soon as the value is parsed. */
+ bool is_mapentry;
+
+ /* If |is_map| or |is_mapentry| is true, |mapfield| refers to the parent
+ * message's map field that we're currently parsing. This differs from |f|
+ * because |f| is the field in the *current* message (i.e., the map-entry
+ * message itself), not the parent's field that leads to this map. */
+ const upb_fielddef *mapfield;
+
+ /* We are in an Any message context. This flag is set when parsing the Any
+ * message and indicates to all field parsers (subobjects, strings, numbers,
+ * and bools) that the parsed field should be serialized as binary data or
+ * cached (type url not found yet). */
+ bool is_any;
+
+ /* The type of packed message in Any. */
+ upb_jsonparser_any_frame *any_frame;
+
+ /* True if the field to be parsed is unknown. */
+ bool is_unknown_field;
+} upb_jsonparser_frame;
+
+static void init_frame(upb_jsonparser_frame* frame) {
+ frame->m = NULL;
+ frame->f = NULL;
+ frame->name_table = NULL;
+ frame->is_repeated = false;
+ frame->is_map = false;
+ frame->is_mapentry = false;
+ frame->mapfield = NULL;
+ frame->is_any = false;
+ frame->any_frame = NULL;
+ frame->is_unknown_field = false;
+}
+
+struct upb_json_parser {
+ upb_arena *arena;
+ const upb_json_parsermethod *method;
+ upb_bytessink input_;
+
+ /* Stack to track the JSON scopes we are in. */
+ upb_jsonparser_frame stack[UPB_JSON_MAX_DEPTH];
+ upb_jsonparser_frame *top;
+ upb_jsonparser_frame *limit;
+
+ upb_status *status;
+
+ /* Ragel's internal parsing stack for the parsing state machine. */
+ int current_state;
+ int parser_stack[UPB_JSON_MAX_DEPTH];
+ int parser_top;
+
+ /* The handle for the current buffer. */
+ const upb_bufhandle *handle;
+
+ /* Accumulate buffer. See details in parser.rl. */
+ const char *accumulated;
+ size_t accumulated_len;
+ char *accumulate_buf;
+ size_t accumulate_buf_size;
+
+ /* Multi-part text data. See details in parser.rl. */
+ int multipart_state;
+ upb_selector_t string_selector;
+
+ /* Input capture. See details in parser.rl. */
+ const char *capture;
+
+ /* Intermediate result of parsing a unicode escape sequence. */
+ uint32_t digit;
+
+ /* For resolve type url in Any. */
+ const upb_symtab *symtab;
+
+ /* Whether to proceed if unknown field is met. */
+ bool ignore_json_unknown;
+
+ /* Cache for parsing timestamp due to base and zone are handled in different
+ * handlers. */
+ struct tm tm;
+};
+
+static upb_jsonparser_frame* start_jsonparser_frame(upb_json_parser *p) {
+ upb_jsonparser_frame *inner;
+ inner = p->top + 1;
+ init_frame(inner);
+ return inner;
+}
+
+struct upb_json_codecache {
+ upb_arena *arena;
+ upb_inttable methods; /* upb_msgdef* -> upb_json_parsermethod* */
+};
+
+struct upb_json_parsermethod {
+ const upb_json_codecache *cache;
+ upb_byteshandler input_handler_;
+
+ /* Maps json_name -> fielddef */
+ upb_strtable name_table;
+};
+
+#define PARSER_CHECK_RETURN(x) if (!(x)) return false
+
+static upb_jsonparser_any_frame *json_parser_any_frame_new(
+ upb_json_parser *p) {
+ upb_jsonparser_any_frame *frame;
+
+ frame = upb_arena_malloc(p->arena, sizeof(upb_jsonparser_any_frame));
+
+ frame->encoder_handlercache = upb_pb_encoder_newcache();
+ frame->parser_codecache = upb_json_codecache_new();
+ frame->parser = NULL;
+ frame->before_type_url_start = NULL;
+ frame->before_type_url_end = NULL;
+ frame->after_type_url_start = NULL;
+
+ upb_stringsink_init(&frame->stringsink);
+
+ return frame;
+}
+
+static void json_parser_any_frame_set_payload_type(
+ upb_json_parser *p,
+ upb_jsonparser_any_frame *frame,
+ const upb_msgdef *payload_type) {
+ const upb_handlers *h;
+ const upb_json_parsermethod *parser_method;
+ upb_pb_encoder *encoder;
+
+ /* Initialize encoder. */
+ h = upb_handlercache_get(frame->encoder_handlercache, payload_type);
+ encoder = upb_pb_encoder_create(p->arena, h, frame->stringsink.sink);
+
+ /* Initialize parser. */
+ parser_method = upb_json_codecache_get(frame->parser_codecache, payload_type);
+ upb_sink_reset(&frame->sink, h, encoder);
+ frame->parser =
+ upb_json_parser_create(p->arena, parser_method, p->symtab, frame->sink,
+ p->status, p->ignore_json_unknown);
+}
+
+static void json_parser_any_frame_free(upb_jsonparser_any_frame *frame) {
+ upb_handlercache_free(frame->encoder_handlercache);
+ upb_json_codecache_free(frame->parser_codecache);
+ upb_stringsink_uninit(&frame->stringsink);
+}
+
+static bool json_parser_any_frame_has_type_url(
+ upb_jsonparser_any_frame *frame) {
+ return frame->parser != NULL;
+}
+
+static bool json_parser_any_frame_has_value_before_type_url(
+ upb_jsonparser_any_frame *frame) {
+ return frame->before_type_url_start != frame->before_type_url_end;
+}
+
+static bool json_parser_any_frame_has_value_after_type_url(
+ upb_jsonparser_any_frame *frame) {
+ return frame->after_type_url_start != NULL;
+}
+
+static bool json_parser_any_frame_has_value(
+ upb_jsonparser_any_frame *frame) {
+ return json_parser_any_frame_has_value_before_type_url(frame) ||
+ json_parser_any_frame_has_value_after_type_url(frame);
+}
+
+static void json_parser_any_frame_set_before_type_url_end(
+ upb_jsonparser_any_frame *frame,
+ const char *ptr) {
+ if (frame->parser == NULL) {
+ frame->before_type_url_end = ptr;
+ }
+}
+
+static void json_parser_any_frame_set_after_type_url_start_once(
+ upb_jsonparser_any_frame *frame,
+ const char *ptr) {
+ if (json_parser_any_frame_has_type_url(frame) &&
+ frame->after_type_url_start == NULL) {
+ frame->after_type_url_start = ptr;
+ }
+}
+
+/* Used to signal that a capture has been suspended. */
+static char suspend_capture;
+
+static upb_selector_t getsel_for_handlertype(upb_json_parser *p,
+ upb_handlertype_t type) {
+ upb_selector_t sel;
+ bool ok = upb_handlers_getselector(p->top->f, type, &sel);
+ UPB_ASSERT(ok);
+ return sel;
+}
+
+static upb_selector_t parser_getsel(upb_json_parser *p) {
+ return getsel_for_handlertype(
+ p, upb_handlers_getprimitivehandlertype(p->top->f));
+}
+
+static bool check_stack(upb_json_parser *p) {
+ if ((p->top + 1) == p->limit) {
+ upb_status_seterrmsg(p->status, "Nesting too deep");
+ return false;
+ }
+
+ return true;
+}
+
+static void set_name_table(upb_json_parser *p, upb_jsonparser_frame *frame) {
+ upb_value v;
+ const upb_json_codecache *cache = p->method->cache;
+ bool ok;
+ const upb_json_parsermethod *method;
+
+ ok = upb_inttable_lookupptr(&cache->methods, frame->m, &v);
+ UPB_ASSERT(ok);
+ method = upb_value_getconstptr(v);
+
+ frame->name_table = &method->name_table;
+}
+
+/* There are GCC/Clang built-ins for overflow checking which we could start
+ * using if there was any performance benefit to it. */
+
+static bool checked_add(size_t a, size_t b, size_t *c) {
+ if (SIZE_MAX - a < b) return false;
+ *c = a + b;
+ return true;
+}
+
+static size_t saturating_multiply(size_t a, size_t b) {
+ /* size_t is unsigned, so this is defined behavior even on overflow. */
+ size_t ret = a * b;
+ if (b != 0 && ret / b != a) {
+ ret = SIZE_MAX;
+ }
+ return ret;
+}
+
+
+/* Base64 decoding ************************************************************/
+
+/* TODO(haberman): make this streaming. */
+
+static const signed char b64table[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 62/*+*/, -1, -1, -1, 63/*/ */,
+ 52/*0*/, 53/*1*/, 54/*2*/, 55/*3*/, 56/*4*/, 57/*5*/, 58/*6*/, 59/*7*/,
+ 60/*8*/, 61/*9*/, -1, -1, -1, -1, -1, -1,
+ -1, 0/*A*/, 1/*B*/, 2/*C*/, 3/*D*/, 4/*E*/, 5/*F*/, 6/*G*/,
+ 07/*H*/, 8/*I*/, 9/*J*/, 10/*K*/, 11/*L*/, 12/*M*/, 13/*N*/, 14/*O*/,
+ 15/*P*/, 16/*Q*/, 17/*R*/, 18/*S*/, 19/*T*/, 20/*U*/, 21/*V*/, 22/*W*/,
+ 23/*X*/, 24/*Y*/, 25/*Z*/, -1, -1, -1, -1, -1,
+ -1, 26/*a*/, 27/*b*/, 28/*c*/, 29/*d*/, 30/*e*/, 31/*f*/, 32/*g*/,
+ 33/*h*/, 34/*i*/, 35/*j*/, 36/*k*/, 37/*l*/, 38/*m*/, 39/*n*/, 40/*o*/,
+ 41/*p*/, 42/*q*/, 43/*r*/, 44/*s*/, 45/*t*/, 46/*u*/, 47/*v*/, 48/*w*/,
+ 49/*x*/, 50/*y*/, 51/*z*/, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+/* Returns the table value sign-extended to 32 bits. Knowing that the upper
+ * bits will be 1 for unrecognized characters makes it easier to check for
+ * this error condition later (see below). */
+int32_t b64lookup(unsigned char ch) { return b64table[ch]; }
+
+/* Returns true if the given character is not a valid base64 character or
+ * padding. */
+bool nonbase64(unsigned char ch) { return b64lookup(ch) == -1 && ch != '='; }
+
+static bool base64_push(upb_json_parser *p, upb_selector_t sel, const char *ptr,
+ size_t len) {
+ const char *limit = ptr + len;
+ for (; ptr < limit; ptr += 4) {
+ uint32_t val;
+ char output[3];
+
+ if (limit - ptr < 4) {
+ upb_status_seterrf(p->status,
+ "Base64 input for bytes field not a multiple of 4: %s",
+ upb_fielddef_name(p->top->f));
+ return false;
+ }
+
+ val = b64lookup(ptr[0]) << 18 |
+ b64lookup(ptr[1]) << 12 |
+ b64lookup(ptr[2]) << 6 |
+ b64lookup(ptr[3]);
+
+ /* Test the upper bit; returns true if any of the characters returned -1. */
+ if (val & 0x80000000) {
+ goto otherchar;
+ }
+
+ output[0] = val >> 16;
+ output[1] = (val >> 8) & 0xff;
+ output[2] = val & 0xff;
+ upb_sink_putstring(p->top->sink, sel, output, 3, NULL);
+ }
+ return true;
+
+otherchar:
+ if (nonbase64(ptr[0]) || nonbase64(ptr[1]) || nonbase64(ptr[2]) ||
+ nonbase64(ptr[3]) ) {
+ upb_status_seterrf(p->status,
+ "Non-base64 characters in bytes field: %s",
+ upb_fielddef_name(p->top->f));
+ return false;
+ } if (ptr[2] == '=') {
+ uint32_t val;
+ char output;
+
+ /* Last group contains only two input bytes, one output byte. */
+ if (ptr[0] == '=' || ptr[1] == '=' || ptr[3] != '=') {
+ goto badpadding;
+ }
+
+ val = b64lookup(ptr[0]) << 18 |
+ b64lookup(ptr[1]) << 12;
+
+ UPB_ASSERT(!(val & 0x80000000));
+ output = val >> 16;
+ upb_sink_putstring(p->top->sink, sel, &output, 1, NULL);
+ return true;
+ } else {
+ uint32_t val;
+ char output[2];
+
+ /* Last group contains only three input bytes, two output bytes. */
+ if (ptr[0] == '=' || ptr[1] == '=' || ptr[2] == '=') {
+ goto badpadding;
+ }
+
+ val = b64lookup(ptr[0]) << 18 |
+ b64lookup(ptr[1]) << 12 |
+ b64lookup(ptr[2]) << 6;
+
+ output[0] = val >> 16;
+ output[1] = (val >> 8) & 0xff;
+ upb_sink_putstring(p->top->sink, sel, output, 2, NULL);
+ return true;
+ }
+
+badpadding:
+ upb_status_seterrf(p->status,
+ "Incorrect base64 padding for field: %s (%.*s)",
+ upb_fielddef_name(p->top->f),
+ 4, ptr);
+ return false;
+}
+
+
+/* Accumulate buffer **********************************************************/
+
+/* Functionality for accumulating a buffer.
+ *
+ * Some parts of the parser need an entire value as a contiguous string. For
+ * example, to look up a member name in a hash table, or to turn a string into
+ * a number, the relevant library routines need the input string to be in
+ * contiguous memory, even if the value spanned two or more buffers in the
+ * input. These routines handle that.
+ *
+ * In the common case we can just point to the input buffer to get this
+ * contiguous string and avoid any actual copy. So we optimistically begin
+ * this way. But there are a few cases where we must instead copy into a
+ * separate buffer:
+ *
+ * 1. The string was not contiguous in the input (it spanned buffers).
+ *
+ * 2. The string included escape sequences that need to be interpreted to get
+ * the true value in a contiguous buffer. */
+
+static void assert_accumulate_empty(upb_json_parser *p) {
+ UPB_ASSERT(p->accumulated == NULL);
+ UPB_ASSERT(p->accumulated_len == 0);
+}
+
+static void accumulate_clear(upb_json_parser *p) {
+ p->accumulated = NULL;
+ p->accumulated_len = 0;
+}
+
+/* Used internally by accumulate_append(). */
+static bool accumulate_realloc(upb_json_parser *p, size_t need) {
+ void *mem;
+ size_t old_size = p->accumulate_buf_size;
+ size_t new_size = UPB_MAX(old_size, 128);
+ while (new_size < need) {
+ new_size = saturating_multiply(new_size, 2);
+ }
+
+ mem = upb_arena_realloc(p->arena, p->accumulate_buf, old_size, new_size);
+ if (!mem) {
+ upb_status_seterrmsg(p->status, "Out of memory allocating buffer.");
+ return false;
+ }
+
+ p->accumulate_buf = mem;
+ p->accumulate_buf_size = new_size;
+ return true;
+}
+
+/* Logically appends the given data to the append buffer.
+ * If "can_alias" is true, we will try to avoid actually copying, but the buffer
+ * must be valid until the next accumulate_append() call (if any). */
+static bool accumulate_append(upb_json_parser *p, const char *buf, size_t len,
+ bool can_alias) {
+ size_t need;
+
+ if (!p->accumulated && can_alias) {
+ p->accumulated = buf;
+ p->accumulated_len = len;
+ return true;
+ }
+
+ if (!checked_add(p->accumulated_len, len, &need)) {
+ upb_status_seterrmsg(p->status, "Integer overflow.");
+ return false;
+ }
+
+ if (need > p->accumulate_buf_size && !accumulate_realloc(p, need)) {
+ return false;
+ }
+
+ if (p->accumulated != p->accumulate_buf) {
+ memcpy(p->accumulate_buf, p->accumulated, p->accumulated_len);
+ p->accumulated = p->accumulate_buf;
+ }
+
+ memcpy(p->accumulate_buf + p->accumulated_len, buf, len);
+ p->accumulated_len += len;
+ return true;
+}
+
+/* Returns a pointer to the data accumulated since the last accumulate_clear()
+ * call, and writes the length to *len. This with point either to the input
+ * buffer or a temporary accumulate buffer. */
+static const char *accumulate_getptr(upb_json_parser *p, size_t *len) {
+ UPB_ASSERT(p->accumulated);
+ *len = p->accumulated_len;
+ return p->accumulated;
+}
+
+
+/* Mult-part text data ********************************************************/
+
+/* When we have text data in the input, it can often come in multiple segments.
+ * For example, there may be some raw string data followed by an escape
+ * sequence. The two segments are processed with different logic. Also buffer
+ * seams in the input can cause multiple segments.
+ *
+ * As we see segments, there are two main cases for how we want to process them:
+ *
+ * 1. we want to push the captured input directly to string handlers.
+ *
+ * 2. we need to accumulate all the parts into a contiguous buffer for further
+ * processing (field name lookup, string->number conversion, etc). */
+
+/* This is the set of states for p->multipart_state. */
+enum {
+ /* We are not currently processing multipart data. */
+ MULTIPART_INACTIVE = 0,
+
+ /* We are processing multipart data by accumulating it into a contiguous
+ * buffer. */
+ MULTIPART_ACCUMULATE = 1,
+
+ /* We are processing multipart data by pushing each part directly to the
+ * current string handlers. */
+ MULTIPART_PUSHEAGERLY = 2
+};
+
+/* Start a multi-part text value where we accumulate the data for processing at
+ * the end. */
+static void multipart_startaccum(upb_json_parser *p) {
+ assert_accumulate_empty(p);
+ UPB_ASSERT(p->multipart_state == MULTIPART_INACTIVE);
+ p->multipart_state = MULTIPART_ACCUMULATE;
+}
+
+/* Start a multi-part text value where we immediately push text data to a string
+ * value with the given selector. */
+static void multipart_start(upb_json_parser *p, upb_selector_t sel) {
+ assert_accumulate_empty(p);
+ UPB_ASSERT(p->multipart_state == MULTIPART_INACTIVE);
+ p->multipart_state = MULTIPART_PUSHEAGERLY;
+ p->string_selector = sel;
+}
+
+static bool multipart_text(upb_json_parser *p, const char *buf, size_t len,
+ bool can_alias) {
+ switch (p->multipart_state) {
+ case MULTIPART_INACTIVE:
+ upb_status_seterrmsg(
+ p->status, "Internal error: unexpected state MULTIPART_INACTIVE");
+ return false;
+
+ case MULTIPART_ACCUMULATE:
+ if (!accumulate_append(p, buf, len, can_alias)) {
+ return false;
+ }
+ break;
+
+ case MULTIPART_PUSHEAGERLY: {
+ const upb_bufhandle *handle = can_alias ? p->handle : NULL;
+ upb_sink_putstring(p->top->sink, p->string_selector, buf, len, handle);
+ break;
+ }
+ }
+
+ return true;
+}
+
+/* Note: this invalidates the accumulate buffer! Call only after reading its
+ * contents. */
+static void multipart_end(upb_json_parser *p) {
+ UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE);
+ p->multipart_state = MULTIPART_INACTIVE;
+ accumulate_clear(p);
+}
+
+
+/* Input capture **************************************************************/
+
+/* Functionality for capturing a region of the input as text. Gracefully
+ * handles the case where a buffer seam occurs in the middle of the captured
+ * region. */
+
+static void capture_begin(upb_json_parser *p, const char *ptr) {
+ UPB_ASSERT(p->multipart_state != MULTIPART_INACTIVE);
+ UPB_ASSERT(p->capture == NULL);
+ p->capture = ptr;
+}
+
+static bool capture_end(upb_json_parser *p, const char *ptr) {
+ UPB_ASSERT(p->capture);
+ if (multipart_text(p, p->capture, ptr - p->capture, true)) {
+ p->capture = NULL;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+/* This is called at the end of each input buffer (ie. when we have hit a
+ * buffer seam). If we are in the middle of capturing the input, this
+ * processes the unprocessed capture region. */
+static void capture_suspend(upb_json_parser *p, const char **ptr) {
+ if (!p->capture) return;
+
+ if (multipart_text(p, p->capture, *ptr - p->capture, false)) {
+ /* We use this as a signal that we were in the middle of capturing, and
+ * that capturing should resume at the beginning of the next buffer.
+ *
+ * We can't use *ptr here, because we have no guarantee that this pointer
+ * will be valid when we resume (if the underlying memory is freed, then
+ * using the pointer at all, even to compare to NULL, is likely undefined
+ * behavior). */
+ p->capture = &suspend_capture;
+ } else {
+ /* Need to back up the pointer to the beginning of the capture, since
+ * we were not able to actually preserve it. */
+ *ptr = p->capture;
+ }
+}
+
+static void capture_resume(upb_json_parser *p, const char *ptr) {
+ if (p->capture) {
+ UPB_ASSERT(p->capture == &suspend_capture);
+ p->capture = ptr;
+ }
+}
+
+
+/* Callbacks from the parser **************************************************/
+
+/* These are the functions called directly from the parser itself.
+ * We define these in the same order as their declarations in the parser. */
+
+static char escape_char(char in) {
+ switch (in) {
+ case 'r': return '\r';
+ case 't': return '\t';
+ case 'n': return '\n';
+ case 'f': return '\f';
+ case 'b': return '\b';
+ case '/': return '/';
+ case '"': return '"';
+ case '\\': return '\\';
+ default:
+ UPB_ASSERT(0);
+ return 'x';
+ }
+}
+
+static bool escape(upb_json_parser *p, const char *ptr) {
+ char ch = escape_char(*ptr);
+ return multipart_text(p, &ch, 1, false);
+}
+
+static void start_hex(upb_json_parser *p) {
+ p->digit = 0;
+}
+
+static void hexdigit(upb_json_parser *p, const char *ptr) {
+ char ch = *ptr;
+
+ p->digit <<= 4;
+
+ if (ch >= '0' && ch <= '9') {
+ p->digit += (ch - '0');
+ } else if (ch >= 'a' && ch <= 'f') {
+ p->digit += ((ch - 'a') + 10);
+ } else {
+ UPB_ASSERT(ch >= 'A' && ch <= 'F');
+ p->digit += ((ch - 'A') + 10);
+ }
+}
+
+static bool end_hex(upb_json_parser *p) {
+ uint32_t codepoint = p->digit;
+
+ /* emit the codepoint as UTF-8. */
+ char utf8[3]; /* support \u0000 -- \uFFFF -- need only three bytes. */
+ int length = 0;
+ if (codepoint <= 0x7F) {
+ utf8[0] = codepoint;
+ length = 1;
+ } else if (codepoint <= 0x07FF) {
+ utf8[1] = (codepoint & 0x3F) | 0x80;
+ codepoint >>= 6;
+ utf8[0] = (codepoint & 0x1F) | 0xC0;
+ length = 2;
+ } else /* codepoint <= 0xFFFF */ {
+ utf8[2] = (codepoint & 0x3F) | 0x80;
+ codepoint >>= 6;
+ utf8[1] = (codepoint & 0x3F) | 0x80;
+ codepoint >>= 6;
+ utf8[0] = (codepoint & 0x0F) | 0xE0;
+ length = 3;
+ }
+ /* TODO(haberman): Handle high surrogates: if codepoint is a high surrogate
+ * we have to wait for the next escape to get the full code point). */
+
+ return multipart_text(p, utf8, length, false);
+}
+
+static void start_text(upb_json_parser *p, const char *ptr) {
+ capture_begin(p, ptr);
+}
+
+static bool end_text(upb_json_parser *p, const char *ptr) {
+ return capture_end(p, ptr);
+}
+
+static bool start_number(upb_json_parser *p, const char *ptr) {
+ if (is_top_level(p)) {
+ if (is_number_wrapper_object(p)) {
+ start_wrapper_object(p);
+ } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
+ start_value_object(p, VALUE_NUMBERVALUE);
+ } else {
+ return false;
+ }
+ } else if (does_number_wrapper_start(p)) {
+ if (!start_subobject(p)) {
+ return false;
+ }
+ start_wrapper_object(p);
+ } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
+ if (!start_subobject(p)) {
+ return false;
+ }
+ start_value_object(p, VALUE_NUMBERVALUE);
+ }
+
+ multipart_startaccum(p);
+ capture_begin(p, ptr);
+ return true;
+}
+
+static bool parse_number(upb_json_parser *p, bool is_quoted);
+
+static bool end_number_nontop(upb_json_parser *p, const char *ptr) {
+ if (!capture_end(p, ptr)) {
+ return false;
+ }
+
+ if (p->top->f == NULL) {
+ multipart_end(p);
+ return true;
+ }
+
+ return parse_number(p, false);
+}
+
+static bool end_number(upb_json_parser *p, const char *ptr) {
+ if (!end_number_nontop(p, ptr)) {
+ return false;
+ }
+
+ if (does_number_wrapper_end(p)) {
+ end_wrapper_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ return true;
+ }
+
+ if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
+ end_value_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ return true;
+ }
+
+ return true;
+}
+
+/* |buf| is NULL-terminated. |buf| itself will never include quotes;
+ * |is_quoted| tells us whether this text originally appeared inside quotes. */
+static bool parse_number_from_buffer(upb_json_parser *p, const char *buf,
+ bool is_quoted) {
+ size_t len = strlen(buf);
+ const char *bufend = buf + len;
+ char *end;
+ upb_fieldtype_t type = upb_fielddef_type(p->top->f);
+ double val;
+ double dummy;
+ double inf = UPB_INFINITY;
+
+ errno = 0;
+
+ if (len == 0 || buf[0] == ' ') {
+ return false;
+ }
+
+ /* For integer types, first try parsing with integer-specific routines.
+ * If these succeed, they will be more accurate for int64/uint64 than
+ * strtod().
+ */
+ switch (type) {
+ case UPB_TYPE_ENUM:
+ case UPB_TYPE_INT32: {
+ long val = strtol(buf, &end, 0);
+ if (errno == ERANGE || end != bufend) {
+ break;
+ } else if (val > INT32_MAX || val < INT32_MIN) {
+ return false;
+ } else {
+ upb_sink_putint32(p->top->sink, parser_getsel(p), val);
+ return true;
+ }
+ }
+ case UPB_TYPE_UINT32: {
+ unsigned long val = strtoul(buf, &end, 0);
+ if (end != bufend) {
+ break;
+ } else if (val > UINT32_MAX || errno == ERANGE) {
+ return false;
+ } else {
+ upb_sink_putuint32(p->top->sink, parser_getsel(p), val);
+ return true;
+ }
+ }
+ /* XXX: We can't handle [u]int64 properly on 32-bit machines because
+ * strto[u]ll isn't in C89. */
+ case UPB_TYPE_INT64: {
+ long val = strtol(buf, &end, 0);
+ if (errno == ERANGE || end != bufend) {
+ break;
+ } else {
+ upb_sink_putint64(p->top->sink, parser_getsel(p), val);
+ return true;
+ }
+ }
+ case UPB_TYPE_UINT64: {
+ unsigned long val = strtoul(p->accumulated, &end, 0);
+ if (end != bufend) {
+ break;
+ } else if (errno == ERANGE) {
+ return false;
+ } else {
+ upb_sink_putuint64(p->top->sink, parser_getsel(p), val);
+ return true;
+ }
+ }
+ default:
+ break;
+ }
+
+ if (type != UPB_TYPE_DOUBLE && type != UPB_TYPE_FLOAT && is_quoted) {
+ /* Quoted numbers for integer types are not allowed to be in double form. */
+ return false;
+ }
+
+ if (len == strlen("Infinity") && strcmp(buf, "Infinity") == 0) {
+ /* C89 does not have an INFINITY macro. */
+ val = inf;
+ } else if (len == strlen("-Infinity") && strcmp(buf, "-Infinity") == 0) {
+ val = -inf;
+ } else {
+ val = strtod(buf, &end);
+ if (errno == ERANGE || end != bufend) {
+ return false;
+ }
+ }
+
+ switch (type) {
+#define CASE(capitaltype, smalltype, ctype, min, max) \
+ case UPB_TYPE_ ## capitaltype: { \
+ if (modf(val, &dummy) != 0 || val > max || val < min) { \
+ return false; \
+ } else { \
+ upb_sink_put ## smalltype(p->top->sink, parser_getsel(p), \
+ (ctype)val); \
+ return true; \
+ } \
+ break; \
+ }
+ case UPB_TYPE_ENUM:
+ CASE(INT32, int32, int32_t, INT32_MIN, INT32_MAX);
+ CASE(INT64, int64, int64_t, INT64_MIN, INT64_MAX);
+ CASE(UINT32, uint32, uint32_t, 0, UINT32_MAX);
+ CASE(UINT64, uint64, uint64_t, 0, UINT64_MAX);
+#undef CASE
+
+ case UPB_TYPE_DOUBLE:
+ upb_sink_putdouble(p->top->sink, parser_getsel(p), val);
+ return true;
+ case UPB_TYPE_FLOAT:
+ if ((val > FLT_MAX || val < -FLT_MAX) && val != inf && val != -inf) {
+ return false;
+ } else {
+ upb_sink_putfloat(p->top->sink, parser_getsel(p), val);
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+static bool parse_number(upb_json_parser *p, bool is_quoted) {
+ size_t len;
+ const char *buf;
+
+ /* strtol() and friends unfortunately do not support specifying the length of
+ * the input string, so we need to force a copy into a NULL-terminated buffer. */
+ if (!multipart_text(p, "\0", 1, false)) {
+ return false;
+ }
+
+ buf = accumulate_getptr(p, &len);
+
+ if (parse_number_from_buffer(p, buf, is_quoted)) {
+ multipart_end(p);
+ return true;
+ } else {
+ upb_status_seterrf(p->status, "error parsing number: %s", buf);
+ multipart_end(p);
+ return false;
+ }
+}
+
+static bool parser_putbool(upb_json_parser *p, bool val) {
+ bool ok;
+
+ if (p->top->f == NULL) {
+ return true;
+ }
+
+ if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL) {
+ upb_status_seterrf(p->status,
+ "Boolean value specified for non-bool field: %s",
+ upb_fielddef_name(p->top->f));
+ return false;
+ }
+
+ ok = upb_sink_putbool(p->top->sink, parser_getsel(p), val);
+ UPB_ASSERT(ok);
+
+ return true;
+}
+
+static bool end_bool(upb_json_parser *p, bool val) {
+ if (is_top_level(p)) {
+ if (is_wellknown_msg(p, UPB_WELLKNOWN_BOOLVALUE)) {
+ start_wrapper_object(p);
+ } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
+ start_value_object(p, VALUE_BOOLVALUE);
+ } else {
+ return false;
+ }
+ } else if (is_wellknown_field(p, UPB_WELLKNOWN_BOOLVALUE)) {
+ if (!start_subobject(p)) {
+ return false;
+ }
+ start_wrapper_object(p);
+ } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
+ if (!start_subobject(p)) {
+ return false;
+ }
+ start_value_object(p, VALUE_BOOLVALUE);
+ }
+
+ if (p->top->is_unknown_field) {
+ return true;
+ }
+
+ if (!parser_putbool(p, val)) {
+ return false;
+ }
+
+ if (is_wellknown_msg(p, UPB_WELLKNOWN_BOOLVALUE)) {
+ end_wrapper_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ return true;
+ }
+
+ if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
+ end_value_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ return true;
+ }
+
+ return true;
+}
+
+static bool end_null(upb_json_parser *p) {
+ const char *zero_ptr = "0";
+
+ if (is_top_level(p)) {
+ if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
+ start_value_object(p, VALUE_NULLVALUE);
+ } else {
+ return true;
+ }
+ } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
+ if (!start_subobject(p)) {
+ return false;
+ }
+ start_value_object(p, VALUE_NULLVALUE);
+ } else {
+ return true;
+ }
+
+ /* Fill null_value field. */
+ multipart_startaccum(p);
+ capture_begin(p, zero_ptr);
+ capture_end(p, zero_ptr + 1);
+ parse_number(p, false);
+
+ end_value_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+
+ return true;
+}
+
+static bool start_any_stringval(upb_json_parser *p) {
+ multipart_startaccum(p);
+ return true;
+}
+
+static bool start_stringval(upb_json_parser *p) {
+ if (is_top_level(p)) {
+ if (is_string_wrapper_object(p) ||
+ is_number_wrapper_object(p)) {
+ start_wrapper_object(p);
+ } else if (is_wellknown_msg(p, UPB_WELLKNOWN_FIELDMASK)) {
+ start_fieldmask_object(p);
+ return true;
+ } else if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) ||
+ is_wellknown_msg(p, UPB_WELLKNOWN_DURATION)) {
+ start_object(p);
+ } else if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
+ start_value_object(p, VALUE_STRINGVALUE);
+ } else {
+ return false;
+ }
+ } else if (does_string_wrapper_start(p) ||
+ does_number_wrapper_start(p)) {
+ if (!start_subobject(p)) {
+ return false;
+ }
+ start_wrapper_object(p);
+ } else if (does_fieldmask_start(p)) {
+ if (!start_subobject(p)) {
+ return false;
+ }
+ start_fieldmask_object(p);
+ return true;
+ } else if (is_wellknown_field(p, UPB_WELLKNOWN_TIMESTAMP) ||
+ is_wellknown_field(p, UPB_WELLKNOWN_DURATION)) {
+ if (!start_subobject(p)) {
+ return false;
+ }
+ start_object(p);
+ } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
+ if (!start_subobject(p)) {
+ return false;
+ }
+ start_value_object(p, VALUE_STRINGVALUE);
+ }
+
+ if (p->top->f == NULL) {
+ multipart_startaccum(p);
+ return true;
+ }
+
+ if (p->top->is_any) {
+ return start_any_stringval(p);
+ }
+
+ if (upb_fielddef_isstring(p->top->f)) {
+ upb_jsonparser_frame *inner;
+ upb_selector_t sel;
+
+ if (!check_stack(p)) return false;
+
+ /* Start a new parser frame: parser frames correspond one-to-one with
+ * handler frames, and string events occur in a sub-frame. */
+ inner = start_jsonparser_frame(p);
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSTR);
+ upb_sink_startstr(p->top->sink, sel, 0, &inner->sink);
+ inner->m = p->top->m;
+ inner->f = p->top->f;
+ p->top = inner;
+
+ if (upb_fielddef_type(p->top->f) == UPB_TYPE_STRING) {
+ /* For STRING fields we push data directly to the handlers as it is
+ * parsed. We don't do this yet for BYTES fields, because our base64
+ * decoder is not streaming.
+ *
+ * TODO(haberman): make base64 decoding streaming also. */
+ multipart_start(p, getsel_for_handlertype(p, UPB_HANDLER_STRING));
+ return true;
+ } else {
+ multipart_startaccum(p);
+ return true;
+ }
+ } else if (upb_fielddef_type(p->top->f) != UPB_TYPE_BOOL &&
+ upb_fielddef_type(p->top->f) != UPB_TYPE_MESSAGE) {
+ /* No need to push a frame -- numeric values in quotes remain in the
+ * current parser frame. These values must accmulate so we can convert
+ * them all at once at the end. */
+ multipart_startaccum(p);
+ return true;
+ } else {
+ upb_status_seterrf(p->status,
+ "String specified for bool or submessage field: %s",
+ upb_fielddef_name(p->top->f));
+ return false;
+ }
+}
+
+static bool end_any_stringval(upb_json_parser *p) {
+ size_t len;
+ const char *buf = accumulate_getptr(p, &len);
+
+ /* Set type_url */
+ upb_selector_t sel;
+ upb_jsonparser_frame *inner;
+ if (!check_stack(p)) return false;
+ inner = p->top + 1;
+
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSTR);
+ upb_sink_startstr(p->top->sink, sel, 0, &inner->sink);
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STRING);
+ upb_sink_putstring(inner->sink, sel, buf, len, NULL);
+ sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSTR);
+ upb_sink_endstr(inner->sink, sel);
+
+ multipart_end(p);
+
+ /* Resolve type url */
+ if (strncmp(buf, "type.googleapis.com/", 20) == 0 && len > 20) {
+ const upb_msgdef *payload_type = NULL;
+ buf += 20;
+ len -= 20;
+
+ payload_type = upb_symtab_lookupmsg2(p->symtab, buf, len);
+ if (payload_type == NULL) {
+ upb_status_seterrf(
+ p->status, "Cannot find packed type: %.*s\n", (int)len, buf);
+ return false;
+ }
+
+ json_parser_any_frame_set_payload_type(p, p->top->any_frame, payload_type);
+
+ return true;
+ } else {
+ upb_status_seterrf(
+ p->status, "Invalid type url: %.*s\n", (int)len, buf);
+ return false;
+ }
+}
+
+static bool end_stringval_nontop(upb_json_parser *p) {
+ bool ok = true;
+
+ if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) ||
+ is_wellknown_msg(p, UPB_WELLKNOWN_DURATION)) {
+ multipart_end(p);
+ return true;
+ }
+
+ if (p->top->f == NULL) {
+ multipart_end(p);
+ return true;
+ }
+
+ if (p->top->is_any) {
+ return end_any_stringval(p);
+ }
+
+ switch (upb_fielddef_type(p->top->f)) {
+ case UPB_TYPE_BYTES:
+ if (!base64_push(p, getsel_for_handlertype(p, UPB_HANDLER_STRING),
+ p->accumulated, p->accumulated_len)) {
+ return false;
+ }
+ /* Fall through. */
+
+ case UPB_TYPE_STRING: {
+ upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSTR);
+ upb_sink_endstr(p->top->sink, sel);
+ p->top--;
+ break;
+ }
+
+ case UPB_TYPE_ENUM: {
+ /* Resolve enum symbolic name to integer value. */
+ const upb_enumdef *enumdef = upb_fielddef_enumsubdef(p->top->f);
+
+ size_t len;
+ const char *buf = accumulate_getptr(p, &len);
+
+ int32_t int_val = 0;
+ ok = upb_enumdef_ntoi(enumdef, buf, len, &int_val);
+
+ if (ok) {
+ upb_selector_t sel = parser_getsel(p);
+ upb_sink_putint32(p->top->sink, sel, int_val);
+ } else {
+ upb_status_seterrf(p->status, "Enum value unknown: '%.*s'", len, buf);
+ }
+
+ break;
+ }
+
+ case UPB_TYPE_INT32:
+ case UPB_TYPE_INT64:
+ case UPB_TYPE_UINT32:
+ case UPB_TYPE_UINT64:
+ case UPB_TYPE_DOUBLE:
+ case UPB_TYPE_FLOAT:
+ ok = parse_number(p, true);
+ break;
+
+ default:
+ UPB_ASSERT(false);
+ upb_status_seterrmsg(p->status, "Internal error in JSON decoder");
+ ok = false;
+ break;
+ }
+
+ multipart_end(p);
+
+ return ok;
+}
+
+static bool end_stringval(upb_json_parser *p) {
+ /* FieldMask's stringvals have been ended when handling them. Only need to
+ * close FieldMask here.*/
+ if (does_fieldmask_end(p)) {
+ end_fieldmask_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ return true;
+ }
+
+ if (!end_stringval_nontop(p)) {
+ return false;
+ }
+
+ if (does_string_wrapper_end(p) ||
+ does_number_wrapper_end(p)) {
+ end_wrapper_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ return true;
+ }
+
+ if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
+ end_value_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ return true;
+ }
+
+ if (is_wellknown_msg(p, UPB_WELLKNOWN_TIMESTAMP) ||
+ is_wellknown_msg(p, UPB_WELLKNOWN_DURATION) ||
+ is_wellknown_msg(p, UPB_WELLKNOWN_FIELDMASK)) {
+ end_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ return true;
+ }
+
+ return true;
+}
+
+static void start_duration_base(upb_json_parser *p, const char *ptr) {
+ capture_begin(p, ptr);
+}
+
+static bool end_duration_base(upb_json_parser *p, const char *ptr) {
+ size_t len;
+ const char *buf;
+ char seconds_buf[14];
+ char nanos_buf[12];
+ char *end;
+ int64_t seconds = 0;
+ int32_t nanos = 0;
+ double val = 0.0;
+ const char *seconds_membername = "seconds";
+ const char *nanos_membername = "nanos";
+ size_t fraction_start;
+
+ if (!capture_end(p, ptr)) {
+ return false;
+ }
+
+ buf = accumulate_getptr(p, &len);
+
+ memset(seconds_buf, 0, 14);
+ memset(nanos_buf, 0, 12);
+
+ /* Find out base end. The maximus duration is 315576000000, which cannot be
+ * represented by double without losing precision. Thus, we need to handle
+ * fraction and base separately. */
+ for (fraction_start = 0; fraction_start < len && buf[fraction_start] != '.';
+ fraction_start++);
+
+ /* Parse base */
+ memcpy(seconds_buf, buf, fraction_start);
+ seconds = strtol(seconds_buf, &end, 10);
+ if (errno == ERANGE || end != seconds_buf + fraction_start) {
+ upb_status_seterrf(p->status, "error parsing duration: %s",
+ seconds_buf);
+ return false;
+ }
+
+ if (seconds > 315576000000) {
+ upb_status_seterrf(p->status, "error parsing duration: "
+ "maximum acceptable value is "
+ "315576000000");
+ return false;
+ }
+
+ if (seconds < -315576000000) {
+ upb_status_seterrf(p->status, "error parsing duration: "
+ "minimum acceptable value is "
+ "-315576000000");
+ return false;
+ }
+
+ /* Parse fraction */
+ nanos_buf[0] = '0';
+ memcpy(nanos_buf + 1, buf + fraction_start, len - fraction_start);
+ val = strtod(nanos_buf, &end);
+ if (errno == ERANGE || end != nanos_buf + len - fraction_start + 1) {
+ upb_status_seterrf(p->status, "error parsing duration: %s",
+ nanos_buf);
+ return false;
+ }
+
+ nanos = val * 1000000000;
+ if (seconds < 0) nanos = -nanos;
+
+ /* Clean up buffer */
+ multipart_end(p);
+
+ /* Set seconds */
+ start_member(p);
+ capture_begin(p, seconds_membername);
+ capture_end(p, seconds_membername + 7);
+ end_membername(p);
+ upb_sink_putint64(p->top->sink, parser_getsel(p), seconds);
+ end_member(p);
+
+ /* Set nanos */
+ start_member(p);
+ capture_begin(p, nanos_membername);
+ capture_end(p, nanos_membername + 5);
+ end_membername(p);
+ upb_sink_putint32(p->top->sink, parser_getsel(p), nanos);
+ end_member(p);
+
+ /* Continue previous arena */
+ multipart_startaccum(p);
+
+ return true;
+}
+
+static int parse_timestamp_number(upb_json_parser *p) {
+ size_t len;
+ const char *buf;
+ int val;
+
+ /* atoi() and friends unfortunately do not support specifying the length of
+ * the input string, so we need to force a copy into a NULL-terminated buffer. */
+ multipart_text(p, "\0", 1, false);
+
+ buf = accumulate_getptr(p, &len);
+ val = atoi(buf);
+ multipart_end(p);
+ multipart_startaccum(p);
+
+ return val;
+}
+
+static void start_year(upb_json_parser *p, const char *ptr) {
+ capture_begin(p, ptr);
+}
+
+static bool end_year(upb_json_parser *p, const char *ptr) {
+ if (!capture_end(p, ptr)) {
+ return false;
+ }
+ p->tm.tm_year = parse_timestamp_number(p) - 1900;
+ return true;
+}
+
+static void start_month(upb_json_parser *p, const char *ptr) {
+ capture_begin(p, ptr);
+}
+
+static bool end_month(upb_json_parser *p, const char *ptr) {
+ if (!capture_end(p, ptr)) {
+ return false;
+ }
+ p->tm.tm_mon = parse_timestamp_number(p) - 1;
+ return true;
+}
+
+static void start_day(upb_json_parser *p, const char *ptr) {
+ capture_begin(p, ptr);
+}
+
+static bool end_day(upb_json_parser *p, const char *ptr) {
+ if (!capture_end(p, ptr)) {
+ return false;
+ }
+ p->tm.tm_mday = parse_timestamp_number(p);
+ return true;
+}
+
+static void start_hour(upb_json_parser *p, const char *ptr) {
+ capture_begin(p, ptr);
+}
+
+static bool end_hour(upb_json_parser *p, const char *ptr) {
+ if (!capture_end(p, ptr)) {
+ return false;
+ }
+ p->tm.tm_hour = parse_timestamp_number(p);
+ return true;
+}
+
+static void start_minute(upb_json_parser *p, const char *ptr) {
+ capture_begin(p, ptr);
+}
+
+static bool end_minute(upb_json_parser *p, const char *ptr) {
+ if (!capture_end(p, ptr)) {
+ return false;
+ }
+ p->tm.tm_min = parse_timestamp_number(p);
+ return true;
+}
+
+static void start_second(upb_json_parser *p, const char *ptr) {
+ capture_begin(p, ptr);
+}
+
+static bool end_second(upb_json_parser *p, const char *ptr) {
+ if (!capture_end(p, ptr)) {
+ return false;
+ }
+ p->tm.tm_sec = parse_timestamp_number(p);
+ return true;
+}
+
+static void start_timestamp_base(upb_json_parser *p) {
+ memset(&p->tm, 0, sizeof(struct tm));
+}
+
+static void start_timestamp_fraction(upb_json_parser *p, const char *ptr) {
+ capture_begin(p, ptr);
+}
+
+static bool end_timestamp_fraction(upb_json_parser *p, const char *ptr) {
+ size_t len;
+ const char *buf;
+ char nanos_buf[12];
+ char *end;
+ double val = 0.0;
+ int32_t nanos;
+ const char *nanos_membername = "nanos";
+
+ memset(nanos_buf, 0, 12);
+
+ if (!capture_end(p, ptr)) {
+ return false;
+ }
+
+ buf = accumulate_getptr(p, &len);
+
+ if (len > 10) {
+ upb_status_seterrf(p->status,
+ "error parsing timestamp: at most 9-digit fraction.");
+ return false;
+ }
+
+ /* Parse nanos */
+ nanos_buf[0] = '0';
+ memcpy(nanos_buf + 1, buf, len);
+ val = strtod(nanos_buf, &end);
+
+ if (errno == ERANGE || end != nanos_buf + len + 1) {
+ upb_status_seterrf(p->status, "error parsing timestamp nanos: %s",
+ nanos_buf);
+ return false;
+ }
+
+ nanos = val * 1000000000;
+
+ /* Clean up previous environment */
+ multipart_end(p);
+
+ /* Set nanos */
+ start_member(p);
+ capture_begin(p, nanos_membername);
+ capture_end(p, nanos_membername + 5);
+ end_membername(p);
+ upb_sink_putint32(p->top->sink, parser_getsel(p), nanos);
+ end_member(p);
+
+ /* Continue previous environment */
+ multipart_startaccum(p);
+
+ return true;
+}
+
+static void start_timestamp_zone(upb_json_parser *p, const char *ptr) {
+ capture_begin(p, ptr);
+}
+
+#define EPOCH_YEAR 1970
+#define TM_YEAR_BASE 1900
+
+static bool isleap(int year) {
+ return (year % 4) == 0 && (year % 100 != 0 || (year % 400) == 0);
+}
+
+const unsigned short int __mon_yday[2][13] = {
+ /* Normal years. */
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
+ /* Leap years. */
+ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
+};
+
+int64_t epoch(int year, int yday, int hour, int min, int sec) {
+ int64_t years = year - EPOCH_YEAR;
+
+ int64_t leap_days = years / 4 - years / 100 + years / 400;
+
+ int64_t days = years * 365 + yday + leap_days;
+ int64_t hours = days * 24 + hour;
+ int64_t mins = hours * 60 + min;
+ int64_t secs = mins * 60 + sec;
+ return secs;
+}
+
+
+static int64_t upb_mktime(const struct tm *tp) {
+ int sec = tp->tm_sec;
+ int min = tp->tm_min;
+ int hour = tp->tm_hour;
+ int mday = tp->tm_mday;
+ int mon = tp->tm_mon;
+ int year = tp->tm_year + TM_YEAR_BASE;
+
+ /* Calculate day of year from year, month, and day of month. */
+ int mon_yday = ((__mon_yday[isleap(year)][mon]) - 1);
+ int yday = mon_yday + mday;
+
+ return epoch(year, yday, hour, min, sec);
+}
+
+static bool end_timestamp_zone(upb_json_parser *p, const char *ptr) {
+ size_t len;
+ const char *buf;
+ int hours;
+ int64_t seconds;
+ const char *seconds_membername = "seconds";
+
+ if (!capture_end(p, ptr)) {
+ return false;
+ }
+
+ buf = accumulate_getptr(p, &len);
+
+ if (buf[0] != 'Z') {
+ if (sscanf(buf + 1, "%2d:00", &hours) != 1) {
+ upb_status_seterrf(p->status, "error parsing timestamp offset");
+ return false;
+ }
+
+ if (buf[0] == '+') {
+ hours = -hours;
+ }
+
+ p->tm.tm_hour += hours;
+ }
+
+ /* Normalize tm */
+ seconds = upb_mktime(&p->tm);
+
+ /* Check timestamp boundary */
+ if (seconds < -62135596800) {
+ upb_status_seterrf(p->status, "error parsing timestamp: "
+ "minimum acceptable value is "
+ "0001-01-01T00:00:00Z");
+ return false;
+ }
+
+ /* Clean up previous environment */
+ multipart_end(p);
+
+ /* Set seconds */
+ start_member(p);
+ capture_begin(p, seconds_membername);
+ capture_end(p, seconds_membername + 7);
+ end_membername(p);
+ upb_sink_putint64(p->top->sink, parser_getsel(p), seconds);
+ end_member(p);
+
+ /* Continue previous environment */
+ multipart_startaccum(p);
+
+ return true;
+}
+
+static void start_fieldmask_path_text(upb_json_parser *p, const char *ptr) {
+ capture_begin(p, ptr);
+}
+
+static bool end_fieldmask_path_text(upb_json_parser *p, const char *ptr) {
+ return capture_end(p, ptr);
+}
+
+static bool start_fieldmask_path(upb_json_parser *p) {
+ upb_jsonparser_frame *inner;
+ upb_selector_t sel;
+
+ if (!check_stack(p)) return false;
+
+ /* Start a new parser frame: parser frames correspond one-to-one with
+ * handler frames, and string events occur in a sub-frame. */
+ inner = start_jsonparser_frame(p);
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSTR);
+ upb_sink_startstr(p->top->sink, sel, 0, &inner->sink);
+ inner->m = p->top->m;
+ inner->f = p->top->f;
+ p->top = inner;
+
+ multipart_startaccum(p);
+ return true;
+}
+
+static bool lower_camel_push(
+ upb_json_parser *p, upb_selector_t sel, const char *ptr, size_t len) {
+ const char *limit = ptr + len;
+ bool first = true;
+ for (;ptr < limit; ptr++) {
+ if (*ptr >= 'A' && *ptr <= 'Z' && !first) {
+ char lower = tolower(*ptr);
+ upb_sink_putstring(p->top->sink, sel, "_", 1, NULL);
+ upb_sink_putstring(p->top->sink, sel, &lower, 1, NULL);
+ } else {
+ upb_sink_putstring(p->top->sink, sel, ptr, 1, NULL);
+ }
+ first = false;
+ }
+ return true;
+}
+
+static bool end_fieldmask_path(upb_json_parser *p) {
+ upb_selector_t sel;
+
+ if (!lower_camel_push(
+ p, getsel_for_handlertype(p, UPB_HANDLER_STRING),
+ p->accumulated, p->accumulated_len)) {
+ return false;
+ }
+
+ sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSTR);
+ upb_sink_endstr(p->top->sink, sel);
+ p->top--;
+
+ multipart_end(p);
+ return true;
+}
+
+static void start_member(upb_json_parser *p) {
+ UPB_ASSERT(!p->top->f);
+ multipart_startaccum(p);
+}
+
+/* Helper: invoked during parse_mapentry() to emit the mapentry message's key
+ * field based on the current contents of the accumulate buffer. */
+static bool parse_mapentry_key(upb_json_parser *p) {
+
+ size_t len;
+ const char *buf = accumulate_getptr(p, &len);
+
+ /* Emit the key field. We do a bit of ad-hoc parsing here because the
+ * parser state machine has already decided that this is a string field
+ * name, and we are reinterpreting it as some arbitrary key type. In
+ * particular, integer and bool keys are quoted, so we need to parse the
+ * quoted string contents here. */
+
+ p->top->f = upb_msgdef_itof(p->top->m, UPB_MAPENTRY_KEY);
+ if (p->top->f == NULL) {
+ upb_status_seterrmsg(p->status, "mapentry message has no key");
+ return false;
+ }
+ switch (upb_fielddef_type(p->top->f)) {
+ case UPB_TYPE_INT32:
+ case UPB_TYPE_INT64:
+ case UPB_TYPE_UINT32:
+ case UPB_TYPE_UINT64:
+ /* Invoke end_number. The accum buffer has the number's text already. */
+ if (!parse_number(p, true)) {
+ return false;
+ }
+ break;
+ case UPB_TYPE_BOOL:
+ if (len == 4 && !strncmp(buf, "true", 4)) {
+ if (!parser_putbool(p, true)) {
+ return false;
+ }
+ } else if (len == 5 && !strncmp(buf, "false", 5)) {
+ if (!parser_putbool(p, false)) {
+ return false;
+ }
+ } else {
+ upb_status_seterrmsg(p->status,
+ "Map bool key not 'true' or 'false'");
+ return false;
+ }
+ multipart_end(p);
+ break;
+ case UPB_TYPE_STRING:
+ case UPB_TYPE_BYTES: {
+ upb_sink subsink;
+ upb_selector_t sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSTR);
+ upb_sink_startstr(p->top->sink, sel, len, &subsink);
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STRING);
+ upb_sink_putstring(subsink, sel, buf, len, NULL);
+ sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSTR);
+ upb_sink_endstr(subsink, sel);
+ multipart_end(p);
+ break;
+ }
+ default:
+ upb_status_seterrmsg(p->status, "Invalid field type for map key");
+ return false;
+ }
+
+ return true;
+}
+
+/* Helper: emit one map entry (as a submessage in the map field sequence). This
+ * is invoked from end_membername(), at the end of the map entry's key string,
+ * with the map key in the accumulate buffer. It parses the key from that
+ * buffer, emits the handler calls to start the mapentry submessage (setting up
+ * its subframe in the process), and sets up state in the subframe so that the
+ * value parser (invoked next) will emit the mapentry's value field and then
+ * end the mapentry message. */
+
+static bool handle_mapentry(upb_json_parser *p) {
+ const upb_fielddef *mapfield;
+ const upb_msgdef *mapentrymsg;
+ upb_jsonparser_frame *inner;
+ upb_selector_t sel;
+
+ /* Map entry: p->top->sink is the seq frame, so we need to start a frame
+ * for the mapentry itself, and then set |f| in that frame so that the map
+ * value field is parsed, and also set a flag to end the frame after the
+ * map-entry value is parsed. */
+ if (!check_stack(p)) return false;
+
+ mapfield = p->top->mapfield;
+ mapentrymsg = upb_fielddef_msgsubdef(mapfield);
+
+ inner = start_jsonparser_frame(p);
+ p->top->f = mapfield;
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSUBMSG);
+ upb_sink_startsubmsg(p->top->sink, sel, &inner->sink);
+ inner->m = mapentrymsg;
+ inner->mapfield = mapfield;
+
+ /* Don't set this to true *yet* -- we reuse parsing handlers below to push
+ * the key field value to the sink, and these handlers will pop the frame
+ * if they see is_mapentry (when invoked by the parser state machine, they
+ * would have just seen the map-entry value, not key). */
+ inner->is_mapentry = false;
+ p->top = inner;
+
+ /* send STARTMSG in submsg frame. */
+ upb_sink_startmsg(p->top->sink);
+
+ parse_mapentry_key(p);
+
+ /* Set up the value field to receive the map-entry value. */
+ p->top->f = upb_msgdef_itof(p->top->m, UPB_MAPENTRY_VALUE);
+ p->top->is_mapentry = true; /* set up to pop frame after value is parsed. */
+ p->top->mapfield = mapfield;
+ if (p->top->f == NULL) {
+ upb_status_seterrmsg(p->status, "mapentry message has no value");
+ return false;
+ }
+
+ return true;
+}
+
+static bool end_membername(upb_json_parser *p) {
+ UPB_ASSERT(!p->top->f);
+
+ if (!p->top->m) {
+ p->top->is_unknown_field = true;
+ multipart_end(p);
+ return true;
+ }
+
+ if (p->top->is_any) {
+ return end_any_membername(p);
+ } else if (p->top->is_map) {
+ return handle_mapentry(p);
+ } else {
+ size_t len;
+ const char *buf = accumulate_getptr(p, &len);
+ upb_value v;
+
+ if (upb_strtable_lookup2(p->top->name_table, buf, len, &v)) {
+ p->top->f = upb_value_getconstptr(v);
+ multipart_end(p);
+
+ return true;
+ } else if (p->ignore_json_unknown) {
+ p->top->is_unknown_field = true;
+ multipart_end(p);
+ return true;
+ } else {
+ upb_status_seterrf(p->status, "No such field: %.*s\n", (int)len, buf);
+ return false;
+ }
+ }
+}
+
+static bool end_any_membername(upb_json_parser *p) {
+ size_t len;
+ const char *buf = accumulate_getptr(p, &len);
+ upb_value v;
+
+ if (len == 5 && strncmp(buf, "@type", len) == 0) {
+ upb_strtable_lookup2(p->top->name_table, "type_url", 8, &v);
+ p->top->f = upb_value_getconstptr(v);
+ multipart_end(p);
+ return true;
+ } else {
+ p->top->is_unknown_field = true;
+ multipart_end(p);
+ return true;
+ }
+}
+
+static void end_member(upb_json_parser *p) {
+ /* If we just parsed a map-entry value, end that frame too. */
+ if (p->top->is_mapentry) {
+ upb_selector_t sel;
+ bool ok;
+ const upb_fielddef *mapfield;
+
+ UPB_ASSERT(p->top > p->stack);
+ /* send ENDMSG on submsg. */
+ upb_sink_endmsg(p->top->sink, p->status);
+ mapfield = p->top->mapfield;
+
+ /* send ENDSUBMSG in repeated-field-of-mapentries frame. */
+ p->top--;
+ ok = upb_handlers_getselector(mapfield, UPB_HANDLER_ENDSUBMSG, &sel);
+ UPB_ASSERT(ok);
+ upb_sink_endsubmsg(p->top->sink, sel);
+ }
+
+ p->top->f = NULL;
+ p->top->is_unknown_field = false;
+}
+
+static void start_any_member(upb_json_parser *p, const char *ptr) {
+ start_member(p);
+ json_parser_any_frame_set_after_type_url_start_once(p->top->any_frame, ptr);
+}
+
+static void end_any_member(upb_json_parser *p, const char *ptr) {
+ json_parser_any_frame_set_before_type_url_end(p->top->any_frame, ptr);
+ end_member(p);
+}
+
+static bool start_subobject(upb_json_parser *p) {
+ if (p->top->is_unknown_field) {
+ if (!check_stack(p)) return false;
+
+ p->top = start_jsonparser_frame(p);
+ return true;
+ }
+
+ if (upb_fielddef_ismap(p->top->f)) {
+ upb_jsonparser_frame *inner;
+ upb_selector_t sel;
+
+ /* Beginning of a map. Start a new parser frame in a repeated-field
+ * context. */
+ if (!check_stack(p)) return false;
+
+ inner = start_jsonparser_frame(p);
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSEQ);
+ upb_sink_startseq(p->top->sink, sel, &inner->sink);
+ inner->m = upb_fielddef_msgsubdef(p->top->f);
+ inner->mapfield = p->top->f;
+ inner->is_map = true;
+ p->top = inner;
+
+ return true;
+ } else if (upb_fielddef_issubmsg(p->top->f)) {
+ upb_jsonparser_frame *inner;
+ upb_selector_t sel;
+
+ /* Beginning of a subobject. Start a new parser frame in the submsg
+ * context. */
+ if (!check_stack(p)) return false;
+
+ inner = start_jsonparser_frame(p);
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSUBMSG);
+ upb_sink_startsubmsg(p->top->sink, sel, &inner->sink);
+ inner->m = upb_fielddef_msgsubdef(p->top->f);
+ set_name_table(p, inner);
+ p->top = inner;
+
+ if (is_wellknown_msg(p, UPB_WELLKNOWN_ANY)) {
+ p->top->is_any = true;
+ p->top->any_frame = json_parser_any_frame_new(p);
+ } else {
+ p->top->is_any = false;
+ p->top->any_frame = NULL;
+ }
+
+ return true;
+ } else {
+ upb_status_seterrf(p->status,
+ "Object specified for non-message/group field: %s",
+ upb_fielddef_name(p->top->f));
+ return false;
+ }
+}
+
+static bool start_subobject_full(upb_json_parser *p) {
+ if (is_top_level(p)) {
+ if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
+ start_value_object(p, VALUE_STRUCTVALUE);
+ if (!start_subobject(p)) return false;
+ start_structvalue_object(p);
+ } else if (is_wellknown_msg(p, UPB_WELLKNOWN_STRUCT)) {
+ start_structvalue_object(p);
+ } else {
+ return true;
+ }
+ } else if (is_wellknown_field(p, UPB_WELLKNOWN_STRUCT)) {
+ if (!start_subobject(p)) return false;
+ start_structvalue_object(p);
+ } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE)) {
+ if (!start_subobject(p)) return false;
+ start_value_object(p, VALUE_STRUCTVALUE);
+ if (!start_subobject(p)) return false;
+ start_structvalue_object(p);
+ }
+
+ return start_subobject(p);
+}
+
+static void end_subobject(upb_json_parser *p) {
+ if (is_top_level(p)) {
+ return;
+ }
+
+ if (p->top->is_map) {
+ upb_selector_t sel;
+ p->top--;
+ sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSEQ);
+ upb_sink_endseq(p->top->sink, sel);
+ } else {
+ upb_selector_t sel;
+ bool is_unknown = p->top->m == NULL;
+ p->top--;
+ if (!is_unknown) {
+ sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSUBMSG);
+ upb_sink_endsubmsg(p->top->sink, sel);
+ }
+ }
+}
+
+static void end_subobject_full(upb_json_parser *p) {
+ end_subobject(p);
+
+ if (is_wellknown_msg(p, UPB_WELLKNOWN_STRUCT)) {
+ end_structvalue_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ }
+
+ if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
+ end_value_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ }
+}
+
+static bool start_array(upb_json_parser *p) {
+ upb_jsonparser_frame *inner;
+ upb_selector_t sel;
+
+ if (is_top_level(p)) {
+ if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
+ start_value_object(p, VALUE_LISTVALUE);
+ if (!start_subobject(p)) return false;
+ start_listvalue_object(p);
+ } else if (is_wellknown_msg(p, UPB_WELLKNOWN_LISTVALUE)) {
+ start_listvalue_object(p);
+ } else {
+ return false;
+ }
+ } else if (is_wellknown_field(p, UPB_WELLKNOWN_LISTVALUE) &&
+ (!upb_fielddef_isseq(p->top->f) ||
+ p->top->is_repeated)) {
+ if (!start_subobject(p)) return false;
+ start_listvalue_object(p);
+ } else if (is_wellknown_field(p, UPB_WELLKNOWN_VALUE) &&
+ (!upb_fielddef_isseq(p->top->f) ||
+ p->top->is_repeated)) {
+ if (!start_subobject(p)) return false;
+ start_value_object(p, VALUE_LISTVALUE);
+ if (!start_subobject(p)) return false;
+ start_listvalue_object(p);
+ }
+
+ if (p->top->is_unknown_field) {
+ inner = start_jsonparser_frame(p);
+ inner->is_unknown_field = true;
+ p->top = inner;
+
+ return true;
+ }
+
+ if (!upb_fielddef_isseq(p->top->f)) {
+ upb_status_seterrf(p->status,
+ "Array specified for non-repeated field: %s",
+ upb_fielddef_name(p->top->f));
+ return false;
+ }
+
+ if (!check_stack(p)) return false;
+
+ inner = start_jsonparser_frame(p);
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSEQ);
+ upb_sink_startseq(p->top->sink, sel, &inner->sink);
+ inner->m = p->top->m;
+ inner->f = p->top->f;
+ inner->is_repeated = true;
+ p->top = inner;
+
+ return true;
+}
+
+static void end_array(upb_json_parser *p) {
+ upb_selector_t sel;
+
+ UPB_ASSERT(p->top > p->stack);
+
+ p->top--;
+
+ if (p->top->is_unknown_field) {
+ return;
+ }
+
+ sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSEQ);
+ upb_sink_endseq(p->top->sink, sel);
+
+ if (is_wellknown_msg(p, UPB_WELLKNOWN_LISTVALUE)) {
+ end_listvalue_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ }
+
+ if (is_wellknown_msg(p, UPB_WELLKNOWN_VALUE)) {
+ end_value_object(p);
+ if (!is_top_level(p)) {
+ end_subobject(p);
+ }
+ }
+}
+
+static void start_object(upb_json_parser *p) {
+ if (!p->top->is_map && p->top->m != NULL) {
+ upb_sink_startmsg(p->top->sink);
+ }
+}
+
+static void end_object(upb_json_parser *p) {
+ if (!p->top->is_map && p->top->m != NULL) {
+ upb_sink_endmsg(p->top->sink, p->status);
+ }
+}
+
+static void start_any_object(upb_json_parser *p, const char *ptr) {
+ start_object(p);
+ p->top->any_frame->before_type_url_start = ptr;
+ p->top->any_frame->before_type_url_end = ptr;
+}
+
+static bool end_any_object(upb_json_parser *p, const char *ptr) {
+ const char *value_membername = "value";
+ bool is_well_known_packed = false;
+ const char *packed_end = ptr + 1;
+ upb_selector_t sel;
+ upb_jsonparser_frame *inner;
+
+ if (json_parser_any_frame_has_value(p->top->any_frame) &&
+ !json_parser_any_frame_has_type_url(p->top->any_frame)) {
+ upb_status_seterrmsg(p->status, "No valid type url");
+ return false;
+ }
+
+ /* Well known types data is represented as value field. */
+ if (upb_msgdef_wellknowntype(p->top->any_frame->parser->top->m) !=
+ UPB_WELLKNOWN_UNSPECIFIED) {
+ is_well_known_packed = true;
+
+ if (json_parser_any_frame_has_value_before_type_url(p->top->any_frame)) {
+ p->top->any_frame->before_type_url_start =
+ memchr(p->top->any_frame->before_type_url_start, ':',
+ p->top->any_frame->before_type_url_end -
+ p->top->any_frame->before_type_url_start);
+ if (p->top->any_frame->before_type_url_start == NULL) {
+ upb_status_seterrmsg(p->status, "invalid data for well known type.");
+ return false;
+ }
+ p->top->any_frame->before_type_url_start++;
+ }
+
+ if (json_parser_any_frame_has_value_after_type_url(p->top->any_frame)) {
+ p->top->any_frame->after_type_url_start =
+ memchr(p->top->any_frame->after_type_url_start, ':',
+ (ptr + 1) -
+ p->top->any_frame->after_type_url_start);
+ if (p->top->any_frame->after_type_url_start == NULL) {
+ upb_status_seterrmsg(p->status, "Invalid data for well known type.");
+ return false;
+ }
+ p->top->any_frame->after_type_url_start++;
+ packed_end = ptr;
+ }
+ }
+
+ if (json_parser_any_frame_has_value_before_type_url(p->top->any_frame)) {
+ if (!parse(p->top->any_frame->parser, NULL,
+ p->top->any_frame->before_type_url_start,
+ p->top->any_frame->before_type_url_end -
+ p->top->any_frame->before_type_url_start, NULL)) {
+ return false;
+ }
+ } else {
+ if (!is_well_known_packed) {
+ if (!parse(p->top->any_frame->parser, NULL, "{", 1, NULL)) {
+ return false;
+ }
+ }
+ }
+
+ if (json_parser_any_frame_has_value_before_type_url(p->top->any_frame) &&
+ json_parser_any_frame_has_value_after_type_url(p->top->any_frame)) {
+ if (!parse(p->top->any_frame->parser, NULL, ",", 1, NULL)) {
+ return false;
+ }
+ }
+
+ if (json_parser_any_frame_has_value_after_type_url(p->top->any_frame)) {
+ if (!parse(p->top->any_frame->parser, NULL,
+ p->top->any_frame->after_type_url_start,
+ packed_end - p->top->any_frame->after_type_url_start, NULL)) {
+ return false;
+ }
+ } else {
+ if (!is_well_known_packed) {
+ if (!parse(p->top->any_frame->parser, NULL, "}", 1, NULL)) {
+ return false;
+ }
+ }
+ }
+
+ if (!end(p->top->any_frame->parser, NULL)) {
+ return false;
+ }
+
+ p->top->is_any = false;
+
+ /* Set value */
+ start_member(p);
+ capture_begin(p, value_membername);
+ capture_end(p, value_membername + 5);
+ end_membername(p);
+
+ if (!check_stack(p)) return false;
+ inner = p->top + 1;
+
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STARTSTR);
+ upb_sink_startstr(p->top->sink, sel, 0, &inner->sink);
+ sel = getsel_for_handlertype(p, UPB_HANDLER_STRING);
+ upb_sink_putstring(inner->sink, sel, p->top->any_frame->stringsink.ptr,
+ p->top->any_frame->stringsink.len, NULL);
+ sel = getsel_for_handlertype(p, UPB_HANDLER_ENDSTR);
+ upb_sink_endstr(inner->sink, sel);
+
+ end_member(p);
+
+ end_object(p);
+
+ /* Deallocate any parse frame. */
+ json_parser_any_frame_free(p->top->any_frame);
+
+ return true;
+}
+
+static bool is_string_wrapper(const upb_msgdef *m) {
+ upb_wellknowntype_t type = upb_msgdef_wellknowntype(m);
+ return type == UPB_WELLKNOWN_STRINGVALUE ||
+ type == UPB_WELLKNOWN_BYTESVALUE;
+}
+
+static bool is_fieldmask(const upb_msgdef *m) {
+ upb_wellknowntype_t type = upb_msgdef_wellknowntype(m);
+ return type == UPB_WELLKNOWN_FIELDMASK;
+}
+
+static void start_fieldmask_object(upb_json_parser *p) {
+ const char *membername = "paths";
+
+ start_object(p);
+
+ /* Set up context for parsing value */
+ start_member(p);
+ capture_begin(p, membername);
+ capture_end(p, membername + 5);
+ end_membername(p);
+
+ start_array(p);
+}
+
+static void end_fieldmask_object(upb_json_parser *p) {
+ end_array(p);
+ end_member(p);
+ end_object(p);
+}
+
+static void start_wrapper_object(upb_json_parser *p) {
+ const char *membername = "value";
+
+ start_object(p);
+
+ /* Set up context for parsing value */
+ start_member(p);
+ capture_begin(p, membername);
+ capture_end(p, membername + 5);
+ end_membername(p);
+}
+
+static void end_wrapper_object(upb_json_parser *p) {
+ end_member(p);
+ end_object(p);
+}
+
+static void start_value_object(upb_json_parser *p, int value_type) {
+ const char *nullmember = "null_value";
+ const char *numbermember = "number_value";
+ const char *stringmember = "string_value";
+ const char *boolmember = "bool_value";
+ const char *structmember = "struct_value";
+ const char *listmember = "list_value";
+ const char *membername = "";
+
+ switch (value_type) {
+ case VALUE_NULLVALUE:
+ membername = nullmember;
+ break;
+ case VALUE_NUMBERVALUE:
+ membername = numbermember;
+ break;
+ case VALUE_STRINGVALUE:
+ membername = stringmember;
+ break;
+ case VALUE_BOOLVALUE:
+ membername = boolmember;
+ break;
+ case VALUE_STRUCTVALUE:
+ membername = structmember;
+ break;
+ case VALUE_LISTVALUE:
+ membername = listmember;
+ break;
+ }
+
+ start_object(p);
+
+ /* Set up context for parsing value */
+ start_member(p);
+ capture_begin(p, membername);
+ capture_end(p, membername + strlen(membername));
+ end_membername(p);
+}
+
+static void end_value_object(upb_json_parser *p) {
+ end_member(p);
+ end_object(p);
+}
+
+static void start_listvalue_object(upb_json_parser *p) {
+ const char *membername = "values";
+
+ start_object(p);
+
+ /* Set up context for parsing value */
+ start_member(p);
+ capture_begin(p, membername);
+ capture_end(p, membername + strlen(membername));
+ end_membername(p);
+}
+
+static void end_listvalue_object(upb_json_parser *p) {
+ end_member(p);
+ end_object(p);
+}
+
+static void start_structvalue_object(upb_json_parser *p) {
+ const char *membername = "fields";
+
+ start_object(p);
+
+ /* Set up context for parsing value */
+ start_member(p);
+ capture_begin(p, membername);
+ capture_end(p, membername + strlen(membername));
+ end_membername(p);
+}
+
+static void end_structvalue_object(upb_json_parser *p) {
+ end_member(p);
+ end_object(p);
+}
+
+static bool is_top_level(upb_json_parser *p) {
+ return p->top == p->stack && p->top->f == NULL && !p->top->is_unknown_field;
+}
+
+static bool is_wellknown_msg(upb_json_parser *p, upb_wellknowntype_t type) {
+ return p->top->m != NULL && upb_msgdef_wellknowntype(p->top->m) == type;
+}
+
+static bool is_wellknown_field(upb_json_parser *p, upb_wellknowntype_t type) {
+ return p->top->f != NULL &&
+ upb_fielddef_issubmsg(p->top->f) &&
+ (upb_msgdef_wellknowntype(upb_fielddef_msgsubdef(p->top->f))
+ == type);
+}
+
+static bool does_number_wrapper_start(upb_json_parser *p) {
+ return p->top->f != NULL &&
+ upb_fielddef_issubmsg(p->top->f) &&
+ upb_msgdef_isnumberwrapper(upb_fielddef_msgsubdef(p->top->f));
+}
+
+static bool does_number_wrapper_end(upb_json_parser *p) {
+ return p->top->m != NULL && upb_msgdef_isnumberwrapper(p->top->m);
+}
+
+static bool is_number_wrapper_object(upb_json_parser *p) {
+ return p->top->m != NULL && upb_msgdef_isnumberwrapper(p->top->m);
+}
+
+static bool does_string_wrapper_start(upb_json_parser *p) {
+ return p->top->f != NULL &&
+ upb_fielddef_issubmsg(p->top->f) &&
+ is_string_wrapper(upb_fielddef_msgsubdef(p->top->f));
+}
+
+static bool does_string_wrapper_end(upb_json_parser *p) {
+ return p->top->m != NULL && is_string_wrapper(p->top->m);
+}
+
+static bool is_string_wrapper_object(upb_json_parser *p) {
+ return p->top->m != NULL && is_string_wrapper(p->top->m);
+}
+
+static bool does_fieldmask_start(upb_json_parser *p) {
+ return p->top->f != NULL &&
+ upb_fielddef_issubmsg(p->top->f) &&
+ is_fieldmask(upb_fielddef_msgsubdef(p->top->f));
+}
+
+static bool does_fieldmask_end(upb_json_parser *p) {
+ return p->top->m != NULL && is_fieldmask(p->top->m);
+}
+
+#define CHECK_RETURN_TOP(x) if (!(x)) goto error
+
+
+/* The actual parser **********************************************************/
+
+/* What follows is the Ragel parser itself. The language is specified in Ragel
+ * and the actions call our C functions above.
+ *
+ * Ragel has an extensive set of functionality, and we use only a small part of
+ * it. There are many action types but we only use a few:
+ *
+ * ">" -- transition into a machine
+ * "%" -- transition out of a machine
+ * "@" -- transition into a final state of a machine.
+ *
+ * "@" transitions are tricky because a machine can transition into a final
+ * state repeatedly. But in some cases we know this can't happen, for example
+ * a string which is delimited by a final '"' can only transition into its
+ * final state once, when the closing '"' is seen. */
+
+
+#line 2794 "upb/json/parser.rl"
+
+
+
+#line 2597 "upb/json/parser.c"
+static const char _json_actions[] = {
+ 0, 1, 0, 1, 1, 1, 3, 1,
+ 4, 1, 6, 1, 7, 1, 8, 1,
+ 9, 1, 11, 1, 12, 1, 13, 1,
+ 14, 1, 15, 1, 16, 1, 17, 1,
+ 18, 1, 19, 1, 20, 1, 22, 1,
+ 23, 1, 24, 1, 35, 1, 37, 1,
+ 39, 1, 40, 1, 42, 1, 43, 1,
+ 44, 1, 46, 1, 48, 1, 49, 1,
+ 50, 1, 51, 1, 53, 1, 54, 2,
+ 4, 9, 2, 5, 6, 2, 7, 3,
+ 2, 7, 9, 2, 21, 26, 2, 25,
+ 10, 2, 27, 28, 2, 29, 30, 2,
+ 32, 34, 2, 33, 31, 2, 38, 36,
+ 2, 40, 42, 2, 45, 2, 2, 46,
+ 54, 2, 47, 36, 2, 49, 54, 2,
+ 50, 54, 2, 51, 54, 2, 52, 41,
+ 2, 53, 54, 3, 32, 34, 35, 4,
+ 21, 26, 27, 28
+};
+
+static const short _json_key_offsets[] = {
+ 0, 0, 12, 13, 18, 23, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 43, 44, 48, 53, 58, 63, 67,
+ 71, 74, 77, 79, 83, 87, 89, 91,
+ 96, 98, 100, 109, 115, 121, 127, 133,
+ 135, 139, 142, 144, 146, 149, 150, 154,
+ 156, 158, 160, 162, 163, 165, 167, 168,
+ 170, 172, 173, 175, 177, 178, 180, 182,
+ 183, 185, 187, 191, 193, 195, 196, 197,
+ 198, 199, 201, 206, 208, 210, 212, 221,
+ 222, 222, 222, 227, 232, 237, 238, 239,
+ 240, 241, 241, 242, 243, 244, 244, 245,
+ 246, 247, 247, 252, 253, 257, 262, 267,
+ 272, 276, 276, 279, 282, 285, 288, 291,
+ 294, 294, 294, 294, 294, 294
+};
+
+static const char _json_trans_keys[] = {
+ 32, 34, 45, 91, 102, 110, 116, 123,
+ 9, 13, 48, 57, 34, 32, 93, 125,
+ 9, 13, 32, 44, 93, 9, 13, 32,
+ 93, 125, 9, 13, 97, 108, 115, 101,
+ 117, 108, 108, 114, 117, 101, 32, 34,
+ 125, 9, 13, 34, 32, 58, 9, 13,
+ 32, 93, 125, 9, 13, 32, 44, 125,
+ 9, 13, 32, 44, 125, 9, 13, 32,
+ 34, 9, 13, 45, 48, 49, 57, 48,
+ 49, 57, 46, 69, 101, 48, 57, 69,
+ 101, 48, 57, 43, 45, 48, 57, 48,
+ 57, 48, 57, 46, 69, 101, 48, 57,
+ 34, 92, 34, 92, 34, 47, 92, 98,
+ 102, 110, 114, 116, 117, 48, 57, 65,
+ 70, 97, 102, 48, 57, 65, 70, 97,
+ 102, 48, 57, 65, 70, 97, 102, 48,
+ 57, 65, 70, 97, 102, 34, 92, 45,
+ 48, 49, 57, 48, 49, 57, 46, 115,
+ 48, 57, 115, 48, 57, 34, 46, 115,
+ 48, 57, 48, 57, 48, 57, 48, 57,
+ 48, 57, 45, 48, 57, 48, 57, 45,
+ 48, 57, 48, 57, 84, 48, 57, 48,
+ 57, 58, 48, 57, 48, 57, 58, 48,
+ 57, 48, 57, 43, 45, 46, 90, 48,
+ 57, 48, 57, 58, 48, 48, 34, 48,
+ 57, 43, 45, 90, 48, 57, 34, 44,
+ 34, 44, 34, 44, 34, 45, 91, 102,
+ 110, 116, 123, 48, 57, 34, 32, 93,
+ 125, 9, 13, 32, 44, 93, 9, 13,
+ 32, 93, 125, 9, 13, 97, 108, 115,
+ 101, 117, 108, 108, 114, 117, 101, 32,
+ 34, 125, 9, 13, 34, 32, 58, 9,
+ 13, 32, 93, 125, 9, 13, 32, 44,
+ 125, 9, 13, 32, 44, 125, 9, 13,
+ 32, 34, 9, 13, 32, 9, 13, 32,
+ 9, 13, 32, 9, 13, 32, 9, 13,
+ 32, 9, 13, 32, 9, 13, 0
+};
+
+static const char _json_single_lengths[] = {
+ 0, 8, 1, 3, 3, 3, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 3, 1, 2, 3, 3, 3, 2, 2,
+ 1, 3, 0, 2, 2, 0, 0, 3,
+ 2, 2, 9, 0, 0, 0, 0, 2,
+ 2, 1, 2, 0, 1, 1, 2, 0,
+ 0, 0, 0, 1, 0, 0, 1, 0,
+ 0, 1, 0, 0, 1, 0, 0, 1,
+ 0, 0, 4, 0, 0, 1, 1, 1,
+ 1, 0, 3, 2, 2, 2, 7, 1,
+ 0, 0, 3, 3, 3, 1, 1, 1,
+ 1, 0, 1, 1, 1, 0, 1, 1,
+ 1, 0, 3, 1, 2, 3, 3, 3,
+ 2, 0, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0
+};
+
+static const char _json_range_lengths[] = {
+ 0, 2, 0, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 3, 3, 3, 3, 0,
+ 1, 1, 0, 1, 1, 0, 1, 1,
+ 1, 1, 1, 0, 1, 1, 0, 1,
+ 1, 0, 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0, 0, 0,
+ 0, 1, 1, 0, 0, 0, 1, 0,
+ 0, 0, 1, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0
+};
+
+static const short _json_index_offsets[] = {
+ 0, 0, 11, 13, 18, 23, 28, 30,
+ 32, 34, 36, 38, 40, 42, 44, 46,
+ 48, 53, 55, 59, 64, 69, 74, 78,
+ 82, 85, 89, 91, 95, 99, 101, 103,
+ 108, 111, 114, 124, 128, 132, 136, 140,
+ 143, 147, 150, 153, 155, 158, 160, 164,
+ 166, 168, 170, 172, 174, 176, 178, 180,
+ 182, 184, 186, 188, 190, 192, 194, 196,
+ 198, 200, 202, 207, 209, 211, 213, 215,
+ 217, 219, 221, 226, 229, 232, 235, 244,
+ 246, 247, 248, 253, 258, 263, 265, 267,
+ 269, 271, 272, 274, 276, 278, 279, 281,
+ 283, 285, 286, 291, 293, 297, 302, 307,
+ 312, 316, 317, 320, 323, 326, 329, 332,
+ 335, 336, 337, 338, 339, 340
+};
+
+static const unsigned char _json_indicies[] = {
+ 0, 2, 3, 4, 5, 6, 7, 8,
+ 0, 3, 1, 9, 1, 11, 12, 1,
+ 11, 10, 13, 14, 12, 13, 1, 14,
+ 1, 1, 14, 10, 15, 1, 16, 1,
+ 17, 1, 18, 1, 19, 1, 20, 1,
+ 21, 1, 22, 1, 23, 1, 24, 1,
+ 25, 26, 27, 25, 1, 28, 1, 29,
+ 30, 29, 1, 30, 1, 1, 30, 31,
+ 32, 33, 34, 32, 1, 35, 36, 27,
+ 35, 1, 36, 26, 36, 1, 37, 38,
+ 39, 1, 38, 39, 1, 41, 42, 42,
+ 40, 43, 1, 42, 42, 43, 40, 44,
+ 44, 45, 1, 45, 1, 45, 40, 41,
+ 42, 42, 39, 40, 47, 48, 46, 50,
+ 51, 49, 52, 52, 52, 52, 52, 52,
+ 52, 52, 53, 1, 54, 54, 54, 1,
+ 55, 55, 55, 1, 56, 56, 56, 1,
+ 57, 57, 57, 1, 59, 60, 58, 61,
+ 62, 63, 1, 64, 65, 1, 66, 67,
+ 1, 68, 1, 67, 68, 1, 69, 1,
+ 66, 67, 65, 1, 70, 1, 71, 1,
+ 72, 1, 73, 1, 74, 1, 75, 1,
+ 76, 1, 77, 1, 78, 1, 79, 1,
+ 80, 1, 81, 1, 82, 1, 83, 1,
+ 84, 1, 85, 1, 86, 1, 87, 1,
+ 88, 1, 89, 89, 90, 91, 1, 92,
+ 1, 93, 1, 94, 1, 95, 1, 96,
+ 1, 97, 1, 98, 1, 99, 99, 100,
+ 98, 1, 102, 1, 101, 104, 105, 103,
+ 1, 1, 101, 106, 107, 108, 109, 110,
+ 111, 112, 107, 1, 113, 1, 114, 115,
+ 117, 118, 1, 117, 116, 119, 120, 118,
+ 119, 1, 120, 1, 1, 120, 116, 121,
+ 1, 122, 1, 123, 1, 124, 1, 125,
+ 126, 1, 127, 1, 128, 1, 129, 130,
+ 1, 131, 1, 132, 1, 133, 134, 135,
+ 136, 134, 1, 137, 1, 138, 139, 138,
+ 1, 139, 1, 1, 139, 140, 141, 142,
+ 143, 141, 1, 144, 145, 136, 144, 1,
+ 145, 135, 145, 1, 146, 147, 147, 1,
+ 148, 148, 1, 149, 149, 1, 150, 150,
+ 1, 151, 151, 1, 152, 152, 1, 1,
+ 1, 1, 1, 1, 1, 0
+};
+
+static const char _json_trans_targs[] = {
+ 1, 0, 2, 107, 3, 6, 10, 13,
+ 16, 106, 4, 3, 106, 4, 5, 7,
+ 8, 9, 108, 11, 12, 109, 14, 15,
+ 110, 16, 17, 111, 18, 18, 19, 20,
+ 21, 22, 111, 21, 22, 24, 25, 31,
+ 112, 26, 28, 27, 29, 30, 33, 113,
+ 34, 33, 113, 34, 32, 35, 36, 37,
+ 38, 39, 33, 113, 34, 41, 42, 46,
+ 42, 46, 43, 45, 44, 114, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 73, 72, 68, 69, 70, 71,
+ 72, 115, 74, 67, 72, 76, 116, 76,
+ 116, 77, 79, 81, 82, 85, 90, 94,
+ 98, 80, 117, 117, 83, 82, 80, 83,
+ 84, 86, 87, 88, 89, 117, 91, 92,
+ 93, 117, 95, 96, 97, 117, 98, 99,
+ 105, 100, 100, 101, 102, 103, 104, 105,
+ 103, 104, 117, 106, 106, 106, 106, 106,
+ 106
+};
+
+static const unsigned char _json_trans_actions[] = {
+ 0, 0, 113, 107, 53, 0, 0, 0,
+ 125, 59, 45, 0, 55, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 101, 51, 47, 0, 0, 45,
+ 49, 49, 104, 0, 0, 0, 0, 0,
+ 3, 0, 0, 0, 0, 0, 5, 15,
+ 0, 0, 71, 7, 13, 0, 74, 9,
+ 9, 9, 77, 80, 11, 37, 37, 37,
+ 0, 0, 0, 39, 0, 41, 86, 0,
+ 0, 0, 17, 19, 0, 21, 23, 0,
+ 25, 27, 0, 29, 31, 0, 33, 35,
+ 0, 135, 83, 135, 0, 0, 0, 0,
+ 0, 92, 0, 89, 89, 98, 43, 0,
+ 131, 95, 113, 107, 53, 0, 0, 0,
+ 125, 59, 69, 110, 45, 0, 55, 0,
+ 0, 0, 0, 0, 0, 119, 0, 0,
+ 0, 122, 0, 0, 0, 116, 0, 101,
+ 51, 47, 0, 0, 45, 49, 49, 104,
+ 0, 0, 128, 0, 57, 63, 65, 61,
+ 67
+};
+
+static const unsigned char _json_eof_actions[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 1, 0, 0, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 57, 63, 65, 61, 67,
+ 0, 0, 0, 0, 0, 0
+};
+
+static const int json_start = 1;
+
+static const int json_en_number_machine = 23;
+static const int json_en_string_machine = 32;
+static const int json_en_duration_machine = 40;
+static const int json_en_timestamp_machine = 47;
+static const int json_en_fieldmask_machine = 75;
+static const int json_en_value_machine = 78;
+static const int json_en_main = 1;
+
+
+#line 2797 "upb/json/parser.rl"
+
+size_t parse(void *closure, const void *hd, const char *buf, size_t size,
+ const upb_bufhandle *handle) {
+ upb_json_parser *parser = closure;
+
+ /* Variables used by Ragel's generated code. */
+ int cs = parser->current_state;
+ int *stack = parser->parser_stack;
+ int top = parser->parser_top;
+
+ const char *p = buf;
+ const char *pe = buf + size;
+ const char *eof = &eof_ch;
+
+ parser->handle = handle;
+
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+
+ capture_resume(parser, buf);
+
+
+#line 2875 "upb/json/parser.c"
+ {
+ int _klen;
+ unsigned int _trans;
+ const char *_acts;
+ unsigned int _nacts;
+ const char *_keys;
+
+ if ( p == pe )
+ goto _test_eof;
+ if ( cs == 0 )
+ goto _out;
+_resume:
+ _keys = _json_trans_keys + _json_key_offsets[cs];
+ _trans = _json_index_offsets[cs];
+
+ _klen = _json_single_lengths[cs];
+ if ( _klen > 0 ) {
+ const char *_lower = _keys;
+ const char *_mid;
+ const char *_upper = _keys + _klen - 1;
+ while (1) {
+ if ( _upper < _lower )
+ break;
+
+ _mid = _lower + ((_upper-_lower) >> 1);
+ if ( (*p) < *_mid )
+ _upper = _mid - 1;
+ else if ( (*p) > *_mid )
+ _lower = _mid + 1;
+ else {
+ _trans += (unsigned int)(_mid - _keys);
+ goto _match;
+ }
+ }
+ _keys += _klen;
+ _trans += _klen;
+ }
+
+ _klen = _json_range_lengths[cs];
+ if ( _klen > 0 ) {
+ const char *_lower = _keys;
+ const char *_mid;
+ const char *_upper = _keys + (_klen<<1) - 2;
+ while (1) {
+ if ( _upper < _lower )
+ break;
+
+ _mid = _lower + (((_upper-_lower) >> 1) & ~1);
+ if ( (*p) < _mid[0] )
+ _upper = _mid - 2;
+ else if ( (*p) > _mid[1] )
+ _lower = _mid + 2;
+ else {
+ _trans += (unsigned int)((_mid - _keys)>>1);
+ goto _match;
+ }
+ }
+ _trans += _klen;
+ }
+
+_match:
+ _trans = _json_indicies[_trans];
+ cs = _json_trans_targs[_trans];
+
+ if ( _json_trans_actions[_trans] == 0 )
+ goto _again;
+
+ _acts = _json_actions + _json_trans_actions[_trans];
+ _nacts = (unsigned int) *_acts++;
+ while ( _nacts-- > 0 )
+ {
+ switch ( *_acts++ )
+ {
+ case 1:
+#line 2602 "upb/json/parser.rl"
+ { p--; {cs = stack[--top]; goto _again;} }
+ break;
+ case 2:
+#line 2604 "upb/json/parser.rl"
+ { p--; {stack[top++] = cs; cs = 23;goto _again;} }
+ break;
+ case 3:
+#line 2608 "upb/json/parser.rl"
+ { start_text(parser, p); }
+ break;
+ case 4:
+#line 2609 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_text(parser, p)); }
+ break;
+ case 5:
+#line 2615 "upb/json/parser.rl"
+ { start_hex(parser); }
+ break;
+ case 6:
+#line 2616 "upb/json/parser.rl"
+ { hexdigit(parser, p); }
+ break;
+ case 7:
+#line 2617 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_hex(parser)); }
+ break;
+ case 8:
+#line 2623 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(escape(parser, p)); }
+ break;
+ case 9:
+#line 2629 "upb/json/parser.rl"
+ { p--; {cs = stack[--top]; goto _again;} }
+ break;
+ case 10:
+#line 2634 "upb/json/parser.rl"
+ { start_year(parser, p); }
+ break;
+ case 11:
+#line 2635 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_year(parser, p)); }
+ break;
+ case 12:
+#line 2639 "upb/json/parser.rl"
+ { start_month(parser, p); }
+ break;
+ case 13:
+#line 2640 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_month(parser, p)); }
+ break;
+ case 14:
+#line 2644 "upb/json/parser.rl"
+ { start_day(parser, p); }
+ break;
+ case 15:
+#line 2645 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_day(parser, p)); }
+ break;
+ case 16:
+#line 2649 "upb/json/parser.rl"
+ { start_hour(parser, p); }
+ break;
+ case 17:
+#line 2650 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_hour(parser, p)); }
+ break;
+ case 18:
+#line 2654 "upb/json/parser.rl"
+ { start_minute(parser, p); }
+ break;
+ case 19:
+#line 2655 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_minute(parser, p)); }
+ break;
+ case 20:
+#line 2659 "upb/json/parser.rl"
+ { start_second(parser, p); }
+ break;
+ case 21:
+#line 2660 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_second(parser, p)); }
+ break;
+ case 22:
+#line 2665 "upb/json/parser.rl"
+ { start_duration_base(parser, p); }
+ break;
+ case 23:
+#line 2666 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_duration_base(parser, p)); }
+ break;
+ case 24:
+#line 2668 "upb/json/parser.rl"
+ { p--; {cs = stack[--top]; goto _again;} }
+ break;
+ case 25:
+#line 2673 "upb/json/parser.rl"
+ { start_timestamp_base(parser); }
+ break;
+ case 26:
+#line 2675 "upb/json/parser.rl"
+ { start_timestamp_fraction(parser, p); }
+ break;
+ case 27:
+#line 2676 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_timestamp_fraction(parser, p)); }
+ break;
+ case 28:
+#line 2678 "upb/json/parser.rl"
+ { start_timestamp_zone(parser, p); }
+ break;
+ case 29:
+#line 2679 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_timestamp_zone(parser, p)); }
+ break;
+ case 30:
+#line 2681 "upb/json/parser.rl"
+ { p--; {cs = stack[--top]; goto _again;} }
+ break;
+ case 31:
+#line 2686 "upb/json/parser.rl"
+ { start_fieldmask_path_text(parser, p); }
+ break;
+ case 32:
+#line 2687 "upb/json/parser.rl"
+ { end_fieldmask_path_text(parser, p); }
+ break;
+ case 33:
+#line 2692 "upb/json/parser.rl"
+ { start_fieldmask_path(parser); }
+ break;
+ case 34:
+#line 2693 "upb/json/parser.rl"
+ { end_fieldmask_path(parser); }
+ break;
+ case 35:
+#line 2699 "upb/json/parser.rl"
+ { p--; {cs = stack[--top]; goto _again;} }
+ break;
+ case 36:
+#line 2704 "upb/json/parser.rl"
+ {
+ if (is_wellknown_msg(parser, UPB_WELLKNOWN_TIMESTAMP)) {
+ {stack[top++] = cs; cs = 47;goto _again;}
+ } else if (is_wellknown_msg(parser, UPB_WELLKNOWN_DURATION)) {
+ {stack[top++] = cs; cs = 40;goto _again;}
+ } else if (is_wellknown_msg(parser, UPB_WELLKNOWN_FIELDMASK)) {
+ {stack[top++] = cs; cs = 75;goto _again;}
+ } else {
+ {stack[top++] = cs; cs = 32;goto _again;}
+ }
+ }
+ break;
+ case 37:
+#line 2717 "upb/json/parser.rl"
+ { p--; {stack[top++] = cs; cs = 78;goto _again;} }
+ break;
+ case 38:
+#line 2722 "upb/json/parser.rl"
+ {
+ if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) {
+ start_any_member(parser, p);
+ } else {
+ start_member(parser);
+ }
+ }
+ break;
+ case 39:
+#line 2729 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_membername(parser)); }
+ break;
+ case 40:
+#line 2732 "upb/json/parser.rl"
+ {
+ if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) {
+ end_any_member(parser, p);
+ } else {
+ end_member(parser);
+ }
+ }
+ break;
+ case 41:
+#line 2743 "upb/json/parser.rl"
+ {
+ if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) {
+ start_any_object(parser, p);
+ } else {
+ start_object(parser);
+ }
+ }
+ break;
+ case 42:
+#line 2752 "upb/json/parser.rl"
+ {
+ if (is_wellknown_msg(parser, UPB_WELLKNOWN_ANY)) {
+ CHECK_RETURN_TOP(end_any_object(parser, p));
+ } else {
+ end_object(parser);
+ }
+ }
+ break;
+ case 43:
+#line 2764 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(start_array(parser)); }
+ break;
+ case 44:
+#line 2768 "upb/json/parser.rl"
+ { end_array(parser); }
+ break;
+ case 45:
+#line 2773 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(start_number(parser, p)); }
+ break;
+ case 46:
+#line 2774 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_number(parser, p)); }
+ break;
+ case 47:
+#line 2776 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(start_stringval(parser)); }
+ break;
+ case 48:
+#line 2777 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_stringval(parser)); }
+ break;
+ case 49:
+#line 2779 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_bool(parser, true)); }
+ break;
+ case 50:
+#line 2781 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_bool(parser, false)); }
+ break;
+ case 51:
+#line 2783 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_null(parser)); }
+ break;
+ case 52:
+#line 2785 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(start_subobject_full(parser)); }
+ break;
+ case 53:
+#line 2786 "upb/json/parser.rl"
+ { end_subobject_full(parser); }
+ break;
+ case 54:
+#line 2791 "upb/json/parser.rl"
+ { p--; {cs = stack[--top]; goto _again;} }
+ break;
+#line 3199 "upb/json/parser.c"
+ }
+ }
+
+_again:
+ if ( cs == 0 )
+ goto _out;
+ if ( ++p != pe )
+ goto _resume;
+ _test_eof: {}
+ if ( p == eof )
+ {
+ const char *__acts = _json_actions + _json_eof_actions[cs];
+ unsigned int __nacts = (unsigned int) *__acts++;
+ while ( __nacts-- > 0 ) {
+ switch ( *__acts++ ) {
+ case 0:
+#line 2600 "upb/json/parser.rl"
+ { p--; {cs = stack[--top]; if ( p == pe )
+ goto _test_eof;
+goto _again;} }
+ break;
+ case 46:
+#line 2774 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_number(parser, p)); }
+ break;
+ case 49:
+#line 2779 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_bool(parser, true)); }
+ break;
+ case 50:
+#line 2781 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_bool(parser, false)); }
+ break;
+ case 51:
+#line 2783 "upb/json/parser.rl"
+ { CHECK_RETURN_TOP(end_null(parser)); }
+ break;
+ case 53:
+#line 2786 "upb/json/parser.rl"
+ { end_subobject_full(parser); }
+ break;
+#line 3241 "upb/json/parser.c"
+ }
+ }
+ }
+
+ _out: {}
+ }
+
+#line 2819 "upb/json/parser.rl"
+
+ if (p != pe) {
+ upb_status_seterrf(parser->status, "Parse error at '%.*s'\n", pe - p, p);
+ } else {
+ capture_suspend(parser, &p);
+ }
+
+error:
+ /* Save parsing state back to parser. */
+ parser->current_state = cs;
+ parser->parser_top = top;
+
+ return p - buf;
+}
+
+static bool end(void *closure, const void *hd) {
+ upb_json_parser *parser = closure;
+
+ /* Prevent compile warning on unused static constants. */
+ UPB_UNUSED(json_start);
+ UPB_UNUSED(json_en_duration_machine);
+ UPB_UNUSED(json_en_fieldmask_machine);
+ UPB_UNUSED(json_en_number_machine);
+ UPB_UNUSED(json_en_string_machine);
+ UPB_UNUSED(json_en_timestamp_machine);
+ UPB_UNUSED(json_en_value_machine);
+ UPB_UNUSED(json_en_main);
+
+ parse(parser, hd, &eof_ch, 0, NULL);
+
+ return parser->current_state >= 106;
+}
+
+static void json_parser_reset(upb_json_parser *p) {
+ int cs;
+ int top;
+
+ p->top = p->stack;
+ init_frame(p->top);
+
+ /* Emit Ragel initialization of the parser. */
+
+#line 3292 "upb/json/parser.c"
+ {
+ cs = json_start;
+ top = 0;
+ }
+
+#line 2861 "upb/json/parser.rl"
+ p->current_state = cs;
+ p->parser_top = top;
+ accumulate_clear(p);
+ p->multipart_state = MULTIPART_INACTIVE;
+ p->capture = NULL;
+ p->accumulated = NULL;
+}
+
+static upb_json_parsermethod *parsermethod_new(upb_json_codecache *c,
+ const upb_msgdef *md) {
+ upb_msg_field_iter i;
+ upb_alloc *alloc = upb_arena_alloc(c->arena);
+
+ upb_json_parsermethod *m = upb_malloc(alloc, sizeof(*m));
+
+ m->cache = c;
+
+ upb_byteshandler_init(&m->input_handler_);
+ upb_byteshandler_setstring(&m->input_handler_, parse, m);
+ upb_byteshandler_setendstr(&m->input_handler_, end, m);
+
+ upb_strtable_init2(&m->name_table, UPB_CTYPE_CONSTPTR, alloc);
+
+ /* Build name_table */
+
+ for(upb_msg_field_begin(&i, md);
+ !upb_msg_field_done(&i);
+ upb_msg_field_next(&i)) {
+ const upb_fielddef *f = upb_msg_iter_field(&i);
+ upb_value v = upb_value_constptr(f);
+ char *buf;
+
+ /* Add an entry for the JSON name. */
+ size_t len = upb_fielddef_getjsonname(f, NULL, 0);
+ buf = upb_malloc(alloc, len);
+ upb_fielddef_getjsonname(f, buf, len);
+ upb_strtable_insert3(&m->name_table, buf, strlen(buf), v, alloc);
+
+ if (strcmp(buf, upb_fielddef_name(f)) != 0) {
+ /* Since the JSON name is different from the regular field name, add an
+ * entry for the raw name (compliant proto3 JSON parsers must accept
+ * both). */
+ const char *name = upb_fielddef_name(f);
+ upb_strtable_insert3(&m->name_table, name, strlen(name), v, alloc);
+ }
+ }
+
+ return m;
+}
+
+/* Public API *****************************************************************/
+
+upb_json_parser *upb_json_parser_create(upb_arena *arena,
+ const upb_json_parsermethod *method,
+ const upb_symtab* symtab,
+ upb_sink output,
+ upb_status *status,
+ bool ignore_json_unknown) {
+#ifndef NDEBUG
+ const size_t size_before = upb_arena_bytesallocated(arena);
+#endif
+ upb_json_parser *p = upb_arena_malloc(arena, sizeof(upb_json_parser));
+ if (!p) return false;
+
+ p->arena = arena;
+ p->method = method;
+ p->status = status;
+ p->limit = p->stack + UPB_JSON_MAX_DEPTH;
+ p->accumulate_buf = NULL;
+ p->accumulate_buf_size = 0;
+ upb_bytessink_reset(&p->input_, &method->input_handler_, p);
+
+ json_parser_reset(p);
+ p->top->sink = output;
+ p->top->m = upb_handlers_msgdef(output.handlers);
+ if (is_wellknown_msg(p, UPB_WELLKNOWN_ANY)) {
+ p->top->is_any = true;
+ p->top->any_frame = json_parser_any_frame_new(p);
+ } else {
+ p->top->is_any = false;
+ p->top->any_frame = NULL;
+ }
+ set_name_table(p, p->top);
+ p->symtab = symtab;
+
+ p->ignore_json_unknown = ignore_json_unknown;
+
+ /* If this fails, uncomment and increase the value in parser.h. */
+ /* fprintf(stderr, "%zd\n", upb_arena_bytesallocated(arena) - size_before); */
+ UPB_ASSERT_DEBUGVAR(upb_arena_bytesallocated(arena) - size_before <=
+ UPB_JSON_PARSER_SIZE);
+ return p;
+}
+
+upb_bytessink upb_json_parser_input(upb_json_parser *p) {
+ return p->input_;
+}
+
+const upb_byteshandler *upb_json_parsermethod_inputhandler(
+ const upb_json_parsermethod *m) {
+ return &m->input_handler_;
+}
+
+upb_json_codecache *upb_json_codecache_new(void) {
+ upb_alloc *alloc;
+ upb_json_codecache *c;
+
+ c = upb_gmalloc(sizeof(*c));
+
+ c->arena = upb_arena_new();
+ alloc = upb_arena_alloc(c->arena);
+
+ upb_inttable_init2(&c->methods, UPB_CTYPE_CONSTPTR, alloc);
+
+ return c;
+}
+
+void upb_json_codecache_free(upb_json_codecache *c) {
+ upb_arena_free(c->arena);
+ upb_gfree(c);
+}
+
+const upb_json_parsermethod *upb_json_codecache_get(upb_json_codecache *c,
+ const upb_msgdef *md) {
+ upb_json_parsermethod *m;
+ upb_value v;
+ upb_msg_field_iter i;
+ upb_alloc *alloc = upb_arena_alloc(c->arena);
+
+ if (upb_inttable_lookupptr(&c->methods, md, &v)) {
+ return upb_value_getconstptr(v);
+ }
+
+ m = parsermethod_new(c, md);
+ v = upb_value_constptr(m);
+
+ if (!m) return NULL;
+ if (!upb_inttable_insertptr2(&c->methods, md, v, alloc)) return NULL;
+
+ /* Populate parser methods for all submessages, so the name tables will
+ * be available during parsing. */
+ for(upb_msg_field_begin(&i, md);
+ !upb_msg_field_done(&i);
+ upb_msg_field_next(&i)) {
+ upb_fielddef *f = upb_msg_iter_field(&i);
+
+ if (upb_fielddef_issubmsg(f)) {
+ const upb_msgdef *subdef = upb_fielddef_msgsubdef(f);
+ const upb_json_parsermethod *sub_method =
+ upb_json_codecache_get(c, subdef);
+
+ if (!sub_method) return NULL;
+ }
+ }
+
+ return m;
+}
diff --git a/third_party/upb/kokoro/ubuntu/build.sh b/third_party/upb/kokoro/ubuntu/build.sh
new file mode 100644
index 00000000000..ad8122b1bdb
--- /dev/null
+++ b/third_party/upb/kokoro/ubuntu/build.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+# Install the latest version of Bazel.
+use_bazel.sh latest
+
+# Verify/query CMake
+echo PATH=$PATH
+ls -l `which cmake`
+cmake --version
+
+# Log the bazel path and version.
+which bazel
+bazel version
+
+cd $(dirname $0)/../..
+bazel test --test_output=errors :all
diff --git a/third_party/upb/kokoro/ubuntu/continuous.cfg b/third_party/upb/kokoro/ubuntu/continuous.cfg
new file mode 100644
index 00000000000..fa97583b342
--- /dev/null
+++ b/third_party/upb/kokoro/ubuntu/continuous.cfg
@@ -0,0 +1,2 @@
+build_file: "upb/kokoro/ubuntu/build.sh"
+timeout_mins: 15
diff --git a/third_party/upb/kokoro/ubuntu/presubmit.cfg b/third_party/upb/kokoro/ubuntu/presubmit.cfg
new file mode 100644
index 00000000000..fa97583b342
--- /dev/null
+++ b/third_party/upb/kokoro/ubuntu/presubmit.cfg
@@ -0,0 +1,2 @@
+build_file: "upb/kokoro/ubuntu/build.sh"
+timeout_mins: 15
diff --git a/third_party/upb/tests/benchmark.cc b/third_party/upb/tests/benchmark.cc
new file mode 100644
index 00000000000..bcb4ec78b63
--- /dev/null
+++ b/third_party/upb/tests/benchmark.cc
@@ -0,0 +1,36 @@
+
+#include
+#include
+#include "google/protobuf/descriptor.upb.h"
+#include "google/protobuf/descriptor.upbdefs.h"
+
+upb_strview descriptor = google_protobuf_descriptor_proto_upbdefinit.descriptor;
+
+/* A buffer big enough to parse descriptor.proto without going to heap. */
+char buf[65535];
+
+static void BM_CreateArena(benchmark::State& state) {
+ for (auto _ : state) {
+ upb_arena* arena = upb_arena_init(buf, sizeof(buf), NULL);
+ upb_arena_free(arena);
+ }
+}
+BENCHMARK(BM_CreateArena);
+
+static void BM_ParseDescriptor(benchmark::State& state) {
+ size_t bytes = 0;
+ for (auto _ : state) {
+ upb_arena* arena = upb_arena_init(buf, sizeof(buf), NULL);
+ google_protobuf_FileDescriptorProto* set =
+ google_protobuf_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_ParseDescriptor);
diff --git a/third_party/upb/tests/bindings/googlepb/test_vs_proto2.cc b/third_party/upb/tests/bindings/googlepb/test_vs_proto2.cc
new file mode 100644
index 00000000000..ac447e1b0cb
--- /dev/null
+++ b/third_party/upb/tests/bindings/googlepb/test_vs_proto2.cc
@@ -0,0 +1,165 @@
+/*
+ *
+ * A test that verifies that our results are identical to proto2 for a
+ * given proto type and input protobuf.
+ */
+
+#define __STDC_LIMIT_MACROS // So we get UINT32_MAX
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "tests/google_messages.pb.h"
+#include "tests/upb_test.h"
+#include "upb/bindings/googlepb/bridge.h"
+#include "upb/def.h"
+#include "upb/handlers.h"
+#include "upb/pb/decoder.h"
+#include "upb/pb/glue.h"
+#include "upb/pb/varint.int.h"
+
+// Pull in string data from tests/google_message{1,2}.dat
+// (the .h files are generated with xxd).
+const unsigned char message1_data[] = {
+#include "tests/google_message1.h"
+};
+
+const unsigned char message2_data[] = {
+#include "tests/google_message2.h"
+};
+
+void compare_metadata(const google::protobuf::Descriptor* d,
+ const upb::MessageDef *upb_md) {
+ ASSERT(d->field_count() == upb_md->field_count());
+ for (upb::MessageDef::const_field_iterator i = upb_md->field_begin();
+ i != upb_md->field_end(); ++i) {
+ const upb::FieldDef* upb_f = *i;
+ const google::protobuf::FieldDescriptor *proto2_f =
+ d->FindFieldByNumber(upb_f->number());
+ ASSERT(upb_f);
+ ASSERT(proto2_f);
+ ASSERT(upb_f->number() == (uint32_t)proto2_f->number());
+ ASSERT(std::string(upb_f->name()) == proto2_f->name());
+ ASSERT(upb_f->descriptor_type() ==
+ static_cast(proto2_f->type()));
+ ASSERT(upb_f->IsSequence() == proto2_f->is_repeated());
+ }
+}
+
+void print_diff(const google::protobuf::Message& msg1,
+ const google::protobuf::Message& msg2) {
+ std::string text_str1;
+ std::string text_str2;
+ google::protobuf::TextFormat::PrintToString(msg1, &text_str1);
+ google::protobuf::TextFormat::PrintToString(msg2, &text_str2);
+ fprintf(stderr, "str1: %s, str2: %s\n", text_str1.c_str(), text_str2.c_str());
+}
+
+void parse_and_compare(google::protobuf::Message *msg1,
+ google::protobuf::Message *msg2,
+ const upb::Handlers *protomsg_handlers,
+ const char *str, size_t len, bool allow_jit) {
+ // Parse to both proto2 and upb.
+ ASSERT(msg1->ParseFromArray(str, len));
+
+ upb::pb::CodeCache cache;
+ ASSERT(cache.set_allow_jit(allow_jit));
+ upb::reffed_ptr decoder_method(
+ cache.GetDecoderMethod(upb::pb::DecoderMethodOptions(protomsg_handlers)));
+
+ upb::Status status;
+ upb::Environment env;
+ env.ReportErrorsTo(&status);
+ upb::Sink protomsg_sink(protomsg_handlers, msg2);
+ upb::pb::Decoder* decoder =
+ upb::pb::Decoder::Create(&env, decoder_method.get(), &protomsg_sink);
+
+ msg2->Clear();
+ bool ok = upb::BufferSource::PutBuffer(str, len, decoder->input());
+ if (!ok) {
+ fprintf(stderr, "error parsing: %s\n", status.error_message());
+ print_diff(*msg1, *msg2);
+ }
+ ASSERT(ok);
+ ASSERT(status.ok());
+
+ // Would like to just compare the message objects themselves, but
+ // unfortunately MessageDifferencer is not part of the open-source release of
+ // proto2, so we compare their serialized strings, which we expect will be
+ // equivalent.
+ std::string str1;
+ std::string str2;
+ msg1->SerializeToString(&str1);
+ msg2->SerializeToString(&str2);
+ if (str1 != str2) {
+ print_diff(*msg1, *msg2);
+ }
+ ASSERT(str1 == str2);
+ ASSERT(std::string(str, len) == str2);
+}
+
+void test_zig_zag() {
+ for (uint64_t num = 5; num * 1.5 < UINT64_MAX; num *= 1.5) {
+ ASSERT(upb_zzenc_64(num) ==
+ google::protobuf::internal::WireFormatLite::ZigZagEncode64(num));
+ if (num < UINT32_MAX) {
+ ASSERT(upb_zzenc_32(num) ==
+ google::protobuf::internal::WireFormatLite::ZigZagEncode32(num));
+ }
+ }
+
+}
+
+extern "C" {
+
+int run_tests(int argc, char *argv[]) {
+ UPB_UNUSED(argc);
+ UPB_UNUSED(argv);
+ UPB_UNUSED(message1_data);
+ UPB_UNUSED(message2_data);
+ size_t len = sizeof(MESSAGE_DATA_IDENT);
+ const char *str = (const char*)MESSAGE_DATA_IDENT;
+
+ MESSAGE_CIDENT msg1;
+ MESSAGE_CIDENT msg2;
+
+ upb::reffed_ptr h(
+ upb::googlepb::WriteHandlers::New(msg1));
+
+ compare_metadata(msg1.GetDescriptor(), h->message_def());
+
+ // Run twice to test proper object reuse.
+ parse_and_compare(&msg1, &msg2, h.get(), str, len, false);
+ parse_and_compare(&msg1, &msg2, h.get(), str, len, true);
+ parse_and_compare(&msg1, &msg2, h.get(), str, len, false);
+ parse_and_compare(&msg1, &msg2, h.get(), str, len, true);
+
+ // Test with DynamicMessage.
+ google::protobuf::DynamicMessageFactory* factory =
+ new google::protobuf::DynamicMessageFactory;
+ const google::protobuf::Message* prototype =
+ factory->GetPrototype(msg1.descriptor());
+ google::protobuf::Message* dyn_msg1 = prototype->New();
+ google::protobuf::Message* dyn_msg2 = prototype->New();
+ h = upb::googlepb::WriteHandlers::New(*dyn_msg1);
+ parse_and_compare(dyn_msg1, dyn_msg2, h.get(), str, len, false);
+ parse_and_compare(dyn_msg1, dyn_msg2, h.get(), str, len, true);
+ delete dyn_msg1;
+ delete dyn_msg2;
+ delete factory;
+
+ test_zig_zag();
+
+ printf("All tests passed, %d assertions.\n", num_assertions);
+
+ google::protobuf::ShutdownProtobufLibrary();
+ return 0;
+}
+
+}
diff --git a/third_party/upb/tests/bindings/lua/test_upb.lua b/third_party/upb/tests/bindings/lua/test_upb.lua
new file mode 100644
index 00000000000..e4edda40032
--- /dev/null
+++ b/third_party/upb/tests/bindings/lua/test_upb.lua
@@ -0,0 +1,750 @@
+
+local upb = require "upb"
+local lunit = require "lunit"
+
+if _VERSION >= 'Lua 5.2' then
+ _ENV = lunit.module("testupb", "seeall")
+else
+ module("testupb", lunit.testcase, package.seeall)
+end
+
+function iter_to_array(iter)
+ local arr = {}
+ for v in iter do
+ arr[#arr + 1] = v
+ end
+ return arr
+end
+
+function test_msgdef()
+ local f2 = upb.FieldDef{name = "field2", number = 1, type = upb.TYPE_INT32}
+ local o = upb.OneofDef{name = "field1", fields = {f2}}
+ local f = upb.FieldDef{name = "field3", number = 2, type = upb.TYPE_INT32}
+
+ local m = upb.MessageDef{fields = {o, f}}
+
+ assert_equal(f, m:lookup_name("field3"))
+ assert_equal(o, m:lookup_name("field1"))
+ assert_equal(f2, m:lookup_name("field2"))
+end
+
+function test_fielddef()
+ local f = upb.FieldDef()
+ assert_false(f:is_frozen())
+ assert_nil(f:number())
+ assert_nil(f:name())
+ assert_nil(f:type())
+ assert_equal(upb.LABEL_OPTIONAL, f:label())
+
+ f:set_name("foo_field")
+ f:set_number(3)
+ f:set_label(upb.LABEL_REPEATED)
+ f:set_type(upb.TYPE_FLOAT)
+
+ assert_equal("foo_field", f:name())
+ assert_equal(3, f:number())
+ assert_equal(upb.LABEL_REPEATED, f:label())
+ assert_equal(upb.TYPE_FLOAT, f:type())
+
+ local f2 = upb.FieldDef{
+ name = "foo", number = 5, type = upb.TYPE_DOUBLE, label = upb.LABEL_REQUIRED
+ }
+
+ assert_equal("foo", f2:name())
+ assert_equal(5, f2:number())
+ assert_equal(upb.TYPE_DOUBLE, f2:type())
+ assert_equal(upb.LABEL_REQUIRED, f2:label())
+end
+
+function test_enumdef()
+ local e = upb.EnumDef()
+ assert_equal(0, #e)
+ assert_nil(e:value(5))
+ assert_nil(e:value("NONEXISTENT_NAME"))
+
+ for name, value in e:values() do
+ fail()
+ end
+
+ e:add("VAL1", 1)
+ e:add("VAL2", 2)
+
+ local values = {}
+ for name, value in e:values() do
+ values[name] = value
+ end
+
+ assert_equal(1, values["VAL1"])
+ assert_equal(2, values["VAL2"])
+
+ local e2 = upb.EnumDef{
+ values = {
+ {"FOO", 1},
+ {"BAR", 77},
+ }
+ }
+
+ assert_equal(1, e2:value("FOO"))
+ assert_equal(77, e2:value("BAR"))
+ assert_equal("FOO", e2:value(1))
+ assert_equal("BAR", e2:value(77))
+
+ e2:freeze()
+
+ local f = upb.FieldDef{type = upb.TYPE_ENUM}
+
+ -- No default set and no EnumDef to get a default from.
+ assert_equal(f:default(), nil)
+
+ f:set_subdef(upb.EnumDef())
+ -- No default to pull in from the EnumDef.
+ assert_equal(f:default(), nil)
+
+ f:set_subdef(e2)
+ -- First member added to e2.
+ assert_equal(f:default(), "FOO")
+
+ f:set_subdef(nil)
+ assert_equal(f:default(), nil)
+
+ f:set_default(1)
+ assert_equal(f:default(), 1)
+
+ f:set_default("YOYOYO")
+ assert_equal(f:default(), "YOYOYO")
+
+ f:set_subdef(e2)
+ f:set_default(1)
+ -- It prefers to return a string, and could resolve the explicit "1" we set
+ -- it to to the string value.
+ assert_equal(f:default(), "FOO")
+
+ -- FieldDef can specify default value by name or number, but the value must
+ -- exist at freeze time.
+ local m1 = upb.build_defs{
+ upb.MessageDef{
+ full_name = "A",
+ fields = {
+ upb.FieldDef{
+ name = "f1",
+ number = 1,
+ type = upb.TYPE_ENUM,
+ subdef = e2,
+ default = "BAR"
+ },
+ upb.FieldDef{
+ name = "f2",
+ number = 2,
+ type = upb.TYPE_ENUM,
+ subdef = e2,
+ default = 77
+ }
+ }
+ }
+ }
+
+ assert_equal(m1:field("f1"):default(), "BAR")
+ assert_equal(m1:field("f1"):default(), "BAR")
+
+ assert_error_match(
+ "enum default for field A.f1 .DOESNT_EXIST. is not in the enum",
+ function()
+ local m1 = upb.build_defs{
+ upb.MessageDef{
+ full_name = "A",
+ fields = {
+ upb.FieldDef{
+ name = "f1",
+ number = 1,
+ type = upb.TYPE_ENUM,
+ subdef = e2,
+ default = "DOESNT_EXIST"
+ }
+ }
+ }
+ }
+ end
+ )
+
+ assert_error_match(
+ "enum default for field A.f1 .142. is not in the enum",
+ function()
+ local m1 = upb.build_defs{
+ upb.MessageDef{
+ full_name = "A",
+ fields = {
+ upb.FieldDef{
+ name = "f1",
+ number = 1,
+ type = upb.TYPE_ENUM,
+ subdef = e2,
+ default = 142
+ }
+ }
+ }
+ }
+ end
+ )
+end
+
+function test_empty_msgdef()
+ local md = upb.MessageDef()
+ assert_nil(md:full_name()) -- Def without name is anonymous.
+ assert_false(md:is_frozen())
+ assert_equal(0, #md)
+ assert_nil(md:field("nonexistent_field"))
+ assert_nil(md:field(3))
+ for field in md:fields() do
+ fail()
+ end
+
+ upb.freeze(md)
+ assert_true(md:is_frozen())
+ assert_equal(0, #md)
+ assert_nil(md:field("nonexistent_field"))
+ assert_nil(md:field(3))
+ for field in md:fields() do
+ fail()
+ end
+end
+
+function test_msgdef_constructor()
+ local f1 = upb.FieldDef{name = "field1", number = 7, type = upb.TYPE_INT32}
+ local f2 = upb.FieldDef{name = "field2", number = 8, type = upb.TYPE_INT32}
+ local md = upb.MessageDef{
+ full_name = "TestMessage",
+ fields = {f1, f2}
+ }
+ assert_equal("TestMessage", md:full_name())
+ assert_false(md:is_frozen())
+ assert_equal(2, #md)
+ assert_equal(f1, md:field("field1"))
+ assert_equal(f2, md:field("field2"))
+ assert_equal(f1, md:field(7))
+ assert_equal(f2, md:field(8))
+ local count = 0
+ local found = {}
+ for field in md:fields() do
+ count = count + 1
+ found[field] = true
+ end
+ assert_equal(2, count)
+ assert_true(found[f1])
+ assert_true(found[f2])
+
+ upb.freeze(md)
+end
+
+function test_iteration()
+ -- Test that we cannot crash the process even if we modify the set of fields
+ -- during iteration.
+ local md = upb.MessageDef{full_name = "TestMessage"}
+
+ for i=1,10 do
+ md:add(upb.FieldDef{
+ name = "field" .. tostring(i),
+ number = 1000 - i,
+ type = upb.TYPE_INT32
+ })
+ end
+
+ local add = #md
+ for f in md:fields() do
+ if add > 0 then
+ add = add - 1
+ for i=10000,11000 do
+ local field_name = "field" .. tostring(i)
+ -- We want to add fields to the table to trigger a table resize,
+ -- but we must skip it if the field name or number already exists
+ -- otherwise it will raise an error.
+ if md:field(field_name) == nil and
+ md:field(i) == nil then
+ md:add(upb.FieldDef{
+ name = field_name,
+ number = i,
+ type = upb.TYPE_INT32
+ })
+ end
+ end
+ end
+ end
+
+ -- Test that iterators don't crash the process even if the MessageDef goes
+ -- out of scope.
+ --
+ -- Note: have previously verified that this can indeed crash the process if
+ -- we do not explicitly add a reference from the iterator to the underlying
+ -- MessageDef.
+ local iter = md:fields()
+ md = nil
+ collectgarbage()
+ while iter() do
+ end
+
+ local ed = upb.EnumDef{
+ values = {
+ {"FOO", 1},
+ {"BAR", 77},
+ }
+ }
+ iter = ed:values()
+ ed = nil
+ collectgarbage()
+ while iter() do
+ end
+end
+
+function test_msgdef_setters()
+ local md = upb.MessageDef()
+ md:set_full_name("Message1")
+ assert_equal("Message1", md:full_name())
+ local f = upb.FieldDef{name = "field1", number = 3, type = upb.TYPE_DOUBLE}
+ md:add(f)
+ assert_equal(1, #md)
+ assert_equal(f, md:field("field1"))
+end
+
+function test_msgdef_errors()
+ assert_error(function() upb.MessageDef{bad_initializer_key = 5} end)
+ local md = upb.MessageDef()
+ assert_error(function()
+ -- Duplicate field number.
+ upb.MessageDef{
+ fields = {
+ upb.FieldDef{name = "field1", number = 1, type = upb.TYPE_INT32},
+ upb.FieldDef{name = "field2", number = 1, type = upb.TYPE_INT32}
+ }
+ }
+ end)
+ assert_error(function()
+ -- Duplicate field name.
+ upb.MessageDef{
+ fields = {
+ upb.FieldDef{name = "field1", number = 1, type = upb.TYPE_INT32},
+ upb.FieldDef{name = "field1", number = 2, type = upb.TYPE_INT32}
+ }
+ }
+ end)
+
+ assert_error(function()
+ -- Duplicate field name.
+ upb.MessageDef{
+ fields = {
+ upb.OneofDef{name = "field1", fields = {
+ upb.FieldDef{name = "field2", number = 1, type = upb.TYPE_INT32},
+ }},
+ upb.FieldDef{name = "field2", number = 2, type = upb.TYPE_INT32}
+ }
+ }
+ end)
+
+ -- attempt to set a name with embedded NULLs.
+ assert_error_match("names cannot have embedded NULLs", function()
+ md:set_full_name("abc\0def")
+ end)
+
+ upb.freeze(md)
+ -- Attempt to mutate frozen MessageDef.
+ assert_error_match("frozen", function()
+ md:add(upb.FieldDef{name = "field1", number = 1, type = upb.TYPE_INT32})
+ end)
+ assert_error_match("frozen", function()
+ md:set_full_name("abc")
+ end)
+
+ -- Attempt to freeze a msgdef without freezing its subdef.
+ assert_error_match("is not frozen or being frozen", function()
+ m1 = upb.MessageDef()
+ upb.freeze(
+ upb.MessageDef{
+ fields = {
+ upb.FieldDef{name = "f1", number = 1, type = upb.TYPE_MESSAGE,
+ subdef = m1}
+ }
+ }
+ )
+ end)
+end
+
+function test_symtab()
+ local empty = upb.SymbolTable()
+ assert_equal(0, #iter_to_array(empty:defs(upb.DEF_ANY)))
+ assert_equal(0, #iter_to_array(empty:defs(upb.DEF_MSG)))
+ assert_equal(0, #iter_to_array(empty:defs(upb.DEF_ENUM)))
+
+ local symtab = upb.SymbolTable{
+ upb.MessageDef{full_name = "TestMessage"},
+ upb.MessageDef{full_name = "ContainingMessage", fields = {
+ upb.FieldDef{name = "field1", number = 1, type = upb.TYPE_INT32},
+ upb.FieldDef{name = "field2", number = 2, type = upb.TYPE_MESSAGE,
+ subdef_name = ".TestMessage"}
+ }
+ }
+ }
+
+ local msgdef1 = symtab:lookup("TestMessage")
+ local msgdef2 = symtab:lookup("ContainingMessage")
+ assert_not_nil(msgdef1)
+ assert_not_nil(msgdef2)
+ assert_equal(msgdef1, msgdef2:field("field2"):subdef())
+ assert_true(msgdef1:is_frozen())
+ assert_true(msgdef2:is_frozen())
+
+ symtab:add{
+ upb.MessageDef{full_name = "ContainingMessage2", fields = {
+ upb.FieldDef{name = "field5", number = 5, type = upb.TYPE_MESSAGE,
+ subdef = msgdef2}
+ }
+ }
+ }
+
+ local msgdef3 = symtab:lookup("ContainingMessage2")
+ assert_not_nil(msgdef3)
+ assert_equal(msgdef3:field("field5"):subdef(), msgdef2)
+end
+
+function test_numeric_array()
+ local function test_for_numeric_type(upb_type, val, too_big, too_small, bad3)
+ local array = upb.Array(upb_type)
+ assert_equal(0, #array)
+
+ -- 0 is never a valid index in Lua.
+ assert_error_match("array index", function() return array[0] end)
+ -- Past the end of the array.
+ assert_error_match("array index", function() return array[1] end)
+
+ array[1] = val
+ assert_equal(val, array[1])
+ assert_equal(1, #array)
+ assert_equal(val, array[1])
+ -- Past the end of the array.
+ assert_error_match("array index", function() return array[2] end)
+
+ array[2] = 10
+ assert_equal(val, array[1])
+ assert_equal(10, array[2])
+ assert_equal(2, #array)
+ -- Past the end of the array.
+ assert_error_match("array index", function() return array[3] end)
+
+ local n = 1
+ for i, val in upb.ipairs(array) do
+ assert_equal(n, i)
+ n = n + 1
+ assert_equal(array[i], val)
+ end
+
+ -- Values that are out of range.
+ local errmsg = "not an integer or out of range"
+ if too_small then
+ assert_error_match(errmsg, function() array[3] = too_small end)
+ end
+ if too_big then
+ assert_error_match(errmsg, function() array[3] = too_big end)
+ end
+ if bad3 then
+ assert_error_match(errmsg, function() array[3] = bad3 end)
+ end
+
+ -- Can't assign other Lua types.
+ errmsg = "bad argument #3"
+ assert_error_match(errmsg, function() array[3] = "abc" end)
+ assert_error_match(errmsg, function() array[3] = true end)
+ assert_error_match(errmsg, function() array[3] = false end)
+ assert_error_match(errmsg, function() array[3] = nil end)
+ assert_error_match(errmsg, function() array[3] = {} end)
+ assert_error_match(errmsg, function() array[3] = print end)
+ assert_error_match(errmsg, function() array[3] = array end)
+ end
+
+ -- in-range of 64-bit types but not exactly representable as double
+ local bad64 = 2^68 - 1
+
+ test_for_numeric_type(upb.TYPE_UINT32, 2^32 - 1, 2^32, -1, 5.1)
+ test_for_numeric_type(upb.TYPE_UINT64, 2^63, 2^64, -1, bad64)
+ test_for_numeric_type(upb.TYPE_INT32, 2^31 - 1, 2^31, -2^31 - 1, 5.1)
+ -- Enums don't exist at a language level in Lua, so we just represent enum
+ -- values as int32s.
+ test_for_numeric_type(upb.TYPE_ENUM, 2^31 - 1, 2^31, -2^31 - 1, 5.1)
+ test_for_numeric_type(upb.TYPE_INT64, 2^62, 2^63, -2^64, bad64)
+ test_for_numeric_type(upb.TYPE_FLOAT, 340282306073709652508363335590014353408)
+ test_for_numeric_type(upb.TYPE_DOUBLE, 10^101)
+end
+
+function test_string_array()
+ local function test_for_string_type(upb_type)
+ local array = upb.Array(upb_type)
+ assert_equal(0, #array)
+
+ -- 0 is never a valid index in Lua.
+ assert_error_match("array index", function() return array[0] end)
+ -- Past the end of the array.
+ assert_error_match("array index", function() return array[1] end)
+
+ array[1] = "foo"
+ assert_equal("foo", array[1])
+ assert_equal(1, #array)
+ -- Past the end of the array.
+ assert_error_match("array index", function() return array[2] end)
+
+ local array2 = upb.Array(upb_type)
+ assert_equal(0, #array2)
+
+ array[2] = "bar"
+ assert_equal("foo", array[1])
+ assert_equal("bar", array[2])
+ assert_equal(2, #array)
+ -- Past the end of the array.
+ assert_error_match("array index", function() return array[3] end)
+
+ local n = 1
+ for i, val in upb.ipairs(array) do
+ assert_equal(n, i)
+ n = n + 1
+ assert_equal(array[i], val)
+ end
+ assert_equal(3, n)
+
+ -- Can't assign other Lua types.
+ assert_error_match("Expected string", function() array[3] = 123 end)
+ assert_error_match("Expected string", function() array[3] = true end)
+ assert_error_match("Expected string", function() array[3] = false end)
+ assert_error_match("Expected string", function() array[3] = nil end)
+ assert_error_match("Expected string", function() array[3] = {} end)
+ assert_error_match("Expected string", function() array[3] = print end)
+ assert_error_match("Expected string", function() array[3] = array end)
+ end
+
+ test_for_string_type(upb.TYPE_STRING)
+ test_for_string_type(upb.TYPE_BYTES)
+end
+
+function test_msg_primitives()
+ local function test_for_numeric_type(upb_type, val, too_big, too_small, bad3)
+ local symtab = upb.SymbolTable{
+ upb.MessageDef{full_name = "TestMessage", fields = {
+ upb.FieldDef{name = "f", number = 1, type = upb_type},
+ }
+ }
+ }
+
+ factory = upb.MessageFactory(symtab)
+ TestMessage = factory:get_message_class("TestMessage")
+ msg = TestMessage()
+
+ -- Defaults to zero
+ assert_equal(0, msg.f)
+
+ msg.f = 0
+ assert_equal(0, msg.f)
+
+ msg.f = val
+ assert_equal(val, msg.f)
+
+ local errmsg = "not an integer or out of range"
+ if too_small then
+ assert_error_match(errmsg, function() msg.f = too_small end)
+ end
+ if too_big then
+ assert_error_match(errmsg, function() msg.f = too_big end)
+ end
+ if bad3 then
+ assert_error_match(errmsg, function() msg.f = bad3 end)
+ end
+
+ -- Can't assign other Lua types.
+ errmsg = "bad argument #3"
+ assert_error_match(errmsg, function() msg.f = "abc" end)
+ assert_error_match(errmsg, function() msg.f = true end)
+ assert_error_match(errmsg, function() msg.f = false end)
+ assert_error_match(errmsg, function() msg.f = nil end)
+ assert_error_match(errmsg, function() msg.f = {} end)
+ assert_error_match(errmsg, function() msg.f = print end)
+ assert_error_match(errmsg, function() msg.f = array end)
+ end
+
+ local symtab = upb.SymbolTable{
+ upb.MessageDef{full_name = "TestMessage", fields = {
+ upb.FieldDef{
+ name = "i32", number = 1, type = upb.TYPE_INT32, default = 1},
+ upb.FieldDef{
+ name = "u32", number = 2, type = upb.TYPE_UINT32, default = 2},
+ upb.FieldDef{
+ name = "i64", number = 3, type = upb.TYPE_INT64, default = 3},
+ upb.FieldDef{
+ name = "u64", number = 4, type = upb.TYPE_UINT64, default = 4},
+ upb.FieldDef{
+ name = "dbl", number = 5, type = upb.TYPE_DOUBLE, default = 5},
+ upb.FieldDef{
+ name = "flt", number = 6, type = upb.TYPE_FLOAT, default = 6},
+ upb.FieldDef{
+ name = "bool", number = 7, type = upb.TYPE_BOOL, default = true},
+ }
+ }
+ }
+
+ factory = upb.MessageFactory(symtab)
+ TestMessage = factory:get_message_class("TestMessage")
+ msg = TestMessage()
+
+ -- Unset member returns default value.
+ -- TODO(haberman): re-enable these when we have descriptor-based reflection.
+ -- assert_equal(1, msg.i32)
+ -- assert_equal(2, msg.u32)
+ -- assert_equal(3, msg.i64)
+ -- assert_equal(4, msg.u64)
+ -- assert_equal(5, msg.dbl)
+ -- assert_equal(6, msg.flt)
+ -- assert_equal(true, msg.bool)
+
+ -- Attempts to access non-existent fields fail.
+ assert_error_match("no such field", function() msg.no_such = 1 end)
+
+ msg.i32 = 10
+ msg.u32 = 20
+ msg.i64 = 30
+ msg.u64 = 40
+ msg.dbl = 50
+ msg.flt = 60
+ msg.bool = true
+
+ assert_equal(10, msg.i32)
+ assert_equal(20, msg.u32)
+ assert_equal(30, msg.i64)
+ assert_equal(40, msg.u64)
+ assert_equal(50, msg.dbl)
+ assert_equal(60, msg.flt)
+ assert_equal(true, msg.bool)
+
+ test_for_numeric_type(upb.TYPE_UINT32, 2^32 - 1, 2^32, -1, 5.1)
+ test_for_numeric_type(upb.TYPE_UINT64, 2^62, 2^64, -1, bad64)
+ test_for_numeric_type(upb.TYPE_INT32, 2^31 - 1, 2^31, -2^31 - 1, 5.1)
+ test_for_numeric_type(upb.TYPE_INT64, 2^61, 2^63, -2^64, bad64)
+ test_for_numeric_type(upb.TYPE_FLOAT, 2^20)
+ test_for_numeric_type(upb.TYPE_DOUBLE, 10^101)
+end
+
+function test_msg_array()
+ local symtab = upb.SymbolTable{
+ upb.MessageDef{full_name = "TestMessage", fields = {
+ upb.FieldDef{name = "i32_array", number = 1, type = upb.TYPE_INT32,
+ label = upb.LABEL_REPEATED},
+ }
+ }
+ }
+
+ factory = upb.MessageFactory(symtab)
+ TestMessage = factory:get_message_class("TestMessage")
+ msg = TestMessage()
+
+ assert_nil(msg.i32_array)
+
+ -- Can't assign a scalar; array is expected.
+ assert_error_match("lupb.array expected", function() msg.i32_array = 5 end)
+
+ -- Can't assign array of the wrong type.
+ local function assign_int64()
+ msg.i32_array = upb.Array(upb.TYPE_INT64)
+ end
+ assert_error_match("Array had incorrect type", assign_int64)
+
+ local arr = upb.Array(upb.TYPE_INT32)
+ msg.i32_array = arr
+ assert_equal(arr, msg.i32_array)
+
+ -- Can't assign other Lua types.
+ assert_error_match("array expected", function() msg.i32_array = "abc" end)
+ assert_error_match("array expected", function() msg.i32_array = true end)
+ assert_error_match("array expected", function() msg.i32_array = false end)
+ assert_error_match("array expected", function() msg.i32_array = nil end)
+ assert_error_match("array expected", function() msg.i32_array = {} end)
+ assert_error_match("array expected", function() msg.i32_array = print end)
+end
+
+function test_msg_submsg()
+ local symtab = upb.SymbolTable{
+ upb.MessageDef{full_name = "TestMessage", fields = {
+ upb.FieldDef{name = "submsg", number = 1, type = upb.TYPE_MESSAGE,
+ subdef_name = ".SubMessage"},
+ }
+ },
+ upb.MessageDef{full_name = "SubMessage"}
+ }
+
+ factory = upb.MessageFactory(symtab)
+ TestMessage = factory:get_message_class("TestMessage")
+ SubMessage = factory:get_message_class("SubMessage")
+ msg = TestMessage()
+
+ assert_nil(msg.submsg)
+
+ -- Can't assign message of the wrong type.
+ local function assign_int64()
+ msg.submsg = TestMessage()
+ end
+ assert_error_match("Message had incorrect type", assign_int64)
+
+ local sub = SubMessage()
+ msg.submsg = sub
+ assert_equal(sub, msg.submsg)
+
+ -- Can't assign other Lua types.
+ assert_error_match("msg expected", function() msg.submsg = "abc" end)
+ assert_error_match("msg expected", function() msg.submsg = true end)
+ assert_error_match("msg expected", function() msg.submsg = false end)
+ assert_error_match("msg expected", function() msg.submsg = nil end)
+ assert_error_match("msg expected", function() msg.submsg = {} end)
+ assert_error_match("msg expected", function() msg.submsg = print end)
+end
+
+-- Lua 5.1 and 5.2 have slightly different semantics for how a finalizer
+-- can be defined in Lua.
+if _VERSION >= 'Lua 5.2' then
+ function defer(fn)
+ setmetatable({}, { __gc = fn })
+ end
+else
+ function defer(fn)
+ getmetatable(newproxy(true)).__gc = fn
+ end
+end
+
+function test_finalizer()
+ -- Tests that we correctly handle a call into an already-finalized object.
+ -- Collectible objects are finalized in the opposite order of creation.
+ do
+ local t = {}
+ defer(function()
+ assert_error_match("called into dead object", function()
+ -- Generic def call.
+ t[1]:full_name()
+ end)
+ assert_error_match("called into dead object", function()
+ -- Specific msgdef call.
+ t[1]:add()
+ end)
+ assert_error_match("called into dead object", function()
+ t[2]:values()
+ end)
+ assert_error_match("called into dead object", function()
+ t[3]:number()
+ end)
+ assert_error_match("called into dead object", function()
+ t[4]:lookup()
+ end)
+ end)
+ t = {
+ upb.MessageDef(),
+ upb.EnumDef(),
+ upb.FieldDef(),
+ upb.SymbolTable(),
+ }
+ end
+ collectgarbage()
+end
+
+local stats = lunit.main()
+
+if stats.failed > 0 or stats.errors > 0 then
+ error("One or more errors in test suite")
+end
diff --git a/third_party/upb/tests/bindings/lua/test_upb.pb.lua b/third_party/upb/tests/bindings/lua/test_upb.pb.lua
new file mode 100644
index 00000000000..ea6de099895
--- /dev/null
+++ b/third_party/upb/tests/bindings/lua/test_upb.pb.lua
@@ -0,0 +1,80 @@
+
+-- Require "pb" first to ensure that the transitive require of "upb" is
+-- handled properly by the "pb" module.
+local pb = require "upb.pb"
+local upb = require "upb"
+local lunit = require "lunit"
+
+if _VERSION >= 'Lua 5.2' then
+ _ENV = lunit.module("testupb_pb", "seeall")
+else
+ module("testupb_pb", lunit.testcase, package.seeall)
+end
+
+local symtab = upb.SymbolTable{
+ upb.MessageDef{full_name = "TestMessage", fields = {
+ upb.FieldDef{name = "i32", number = 1, type = upb.TYPE_INT32},
+ upb.FieldDef{name = "u32", number = 2, type = upb.TYPE_UINT32},
+ upb.FieldDef{name = "i64", number = 3, type = upb.TYPE_INT64},
+ upb.FieldDef{name = "u64", number = 4, type = upb.TYPE_UINT64},
+ upb.FieldDef{name = "dbl", number = 5, type = upb.TYPE_DOUBLE},
+ upb.FieldDef{name = "flt", number = 6, type = upb.TYPE_FLOAT},
+ upb.FieldDef{name = "bool", number = 7, type = upb.TYPE_BOOL},
+ }
+ }
+}
+
+local factory = upb.MessageFactory(symtab);
+local TestMessage = factory:get_message_class("TestMessage")
+
+function test_parse_primitive()
+ local binary_pb =
+ "\008\128\128\128\128\002\016\128\128\128\128\004\024\128\128"
+ .. "\128\128\128\128\128\002\032\128\128\128\128\128\128\128\001\041\000"
+ .. "\000\000\000\000\000\248\063\053\000\000\096\064\056\001"
+ local msg = TestMessage()
+ pb.decode(msg, binary_pb)
+ assert_equal(536870912, msg.i32)
+ assert_equal(1073741824, msg.u32)
+ assert_equal(1125899906842624, msg.i64)
+ assert_equal(562949953421312, msg.u64)
+ assert_equal(1.5, msg.dbl)
+ assert_equal(3.5, msg.flt)
+ assert_equal(true, msg.bool)
+
+ local encoded = pb.encode(msg)
+ local msg2 = TestMessage()
+ pb.decode(msg2, encoded)
+ assert_equal(536870912, msg.i32)
+ assert_equal(1073741824, msg.u32)
+ assert_equal(1125899906842624, msg.i64)
+ assert_equal(562949953421312, msg.u64)
+ assert_equal(1.5, msg.dbl)
+ assert_equal(3.5, msg.flt)
+ assert_equal(true, msg.bool)
+end
+
+function test_parse_string()
+ local symtab = upb.SymbolTable{
+ upb.MessageDef{full_name = "TestMessage", fields = {
+ upb.FieldDef{name = "str", number = 1, type = upb.TYPE_STRING},
+ }
+ }
+ }
+
+ local factory = upb.MessageFactory(symtab);
+ local TestMessage = factory:get_message_class("TestMessage")
+
+ local binary_pb = "\010\005Hello"
+ msg = TestMessage()
+ pb.decode(msg, binary_pb)
+ -- TODO(haberman): re-enable when this stuff works better.
+ -- assert_equal("Hello", msg.str)
+end
+
+
+local stats = lunit.main()
+
+if stats.failed > 0 or stats.errors > 0 then
+ error("One or more errors in test suite")
+end
diff --git a/third_party/upb/tests/bindings/ruby/upb.rb b/third_party/upb/tests/bindings/ruby/upb.rb
new file mode 100644
index 00000000000..3e06c1798c6
--- /dev/null
+++ b/third_party/upb/tests/bindings/ruby/upb.rb
@@ -0,0 +1,62 @@
+#!/usr/bin/ruby
+#
+# Tests for Ruby upb extension.
+
+require 'test/unit'
+require 'set'
+require 'upb'
+
+def get_descriptor
+ File.open("upb/descriptor/descriptor.pb").read
+end
+
+def load_descriptor
+ symtab = Upb::SymbolTable.new
+ symtab.load_descriptor(get_descriptor())
+ return symtab
+end
+
+def get_message_class(name)
+ return Upb.get_message_class(load_descriptor().lookup(name))
+end
+
+class TestRubyExtension < Test::Unit::TestCase
+ def test_parsedescriptor
+ msgdef = load_descriptor.lookup("google.protobuf.FileDescriptorSet")
+ assert_instance_of(Upb::MessageDef, msgdef)
+
+ file_descriptor_set = Upb.get_message_class(msgdef)
+ msg = file_descriptor_set.parse(get_descriptor())
+
+ # A couple message types we know should exist.
+ names = Set.new(["DescriptorProto", "FieldDescriptorProto"])
+
+ msg.file.each { |file|
+ file.message_type.each { |message_type|
+ names.delete(message_type.name)
+ }
+ }
+
+ assert_equal(0, names.size)
+ end
+
+ def test_parseserialize
+ field_descriptor_proto = get_message_class("google.protobuf.FieldDescriptorProto")
+ field_options = get_message_class("google.protobuf.FieldOptions")
+
+ field = field_descriptor_proto.new
+
+ field.name = "MyName"
+ field.number = 5
+ field.options = field_options.new
+ field.options.packed = true
+
+ serialized = Upb::Message.serialize(field)
+
+ field2 = field_descriptor_proto.parse(serialized)
+
+ assert_equal("MyName", field2.name)
+ assert_equal(5, field2.number)
+ assert_equal(true, field2.options.packed)
+ end
+end
diff --git a/third_party/upb/tests/conformance_upb.c b/third_party/upb/tests/conformance_upb.c
new file mode 100644
index 00000000000..6063c9941ed
--- /dev/null
+++ b/third_party/upb/tests/conformance_upb.c
@@ -0,0 +1,179 @@
+/* This is a upb implementation of the upb conformance tests, see:
+ * https://github.com/google/protobuf/tree/master/conformance
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include "conformance/conformance.upb.h"
+#include "src/google/protobuf/test_messages_proto3.upb.h"
+
+int test_count = 0;
+
+bool CheckedRead(int fd, void *buf, size_t len) {
+ size_t ofs = 0;
+ while (len > 0) {
+ ssize_t bytes_read = read(fd, (char*)buf + ofs, len);
+
+ if (bytes_read == 0) return false;
+
+ if (bytes_read < 0) {
+ perror("reading from test runner");
+ exit(1);
+ }
+
+ len -= bytes_read;
+ ofs += bytes_read;
+ }
+
+ return true;
+}
+
+void CheckedWrite(int fd, const void *buf, size_t len) {
+ if ((size_t)write(fd, buf, len) != len) {
+ perror("writing to test runner");
+ exit(1);
+ }
+}
+
+bool strview_eql(upb_strview view, const char *str) {
+ return view.size == strlen(str) && memcmp(view.data, str, view.size) == 0;
+}
+
+static const char *proto3_msg =
+ "protobuf_test_messages.proto3.TestAllTypesProto3";
+
+void DoTest(
+ const conformance_ConformanceRequest* request,
+ conformance_ConformanceResponse *response,
+ upb_arena *arena) {
+ protobuf_test_messages_proto3_TestAllTypesProto3 *test_message;
+
+ if (!strview_eql(conformance_ConformanceRequest_message_type(request),
+ proto3_msg)) {
+ static const char msg[] = "Only proto3 for now.";
+ conformance_ConformanceResponse_set_skipped(
+ response, upb_strview_make(msg, sizeof(msg)));
+ return;
+ }
+
+ switch (conformance_ConformanceRequest_payload_case(request)) {
+ case conformance_ConformanceRequest_payload_protobuf_payload: {
+ upb_strview payload = conformance_ConformanceRequest_protobuf_payload(request);
+ test_message = protobuf_test_messages_proto3_TestAllTypesProto3_parse(
+ payload.data, payload.size, arena);
+
+ if (!test_message) {
+ static const char msg[] = "Parse error";
+ conformance_ConformanceResponse_set_parse_error(
+ response, upb_strview_make(msg, sizeof(msg)));
+ return;
+ }
+ break;
+ }
+
+ case conformance_ConformanceRequest_payload_NOT_SET:
+ fprintf(stderr, "conformance_upb: Request didn't have payload.\n");
+ return;
+
+ default: {
+ static const char msg[] = "Unsupported input format.";
+ conformance_ConformanceResponse_set_skipped(
+ response, upb_strview_make(msg, sizeof(msg)));
+ return;
+ }
+ }
+
+ switch (conformance_ConformanceRequest_requested_output_format(request)) {
+ case conformance_UNSPECIFIED:
+ fprintf(stderr, "conformance_upb: Unspecified output format.\n");
+ exit(1);
+
+ case conformance_PROTOBUF: {
+ size_t serialized_len;
+ char *serialized =
+ protobuf_test_messages_proto3_TestAllTypesProto3_serialize(
+ test_message, arena, &serialized_len);
+ if (!serialized) {
+ static const char msg[] = "Error serializing.";
+ conformance_ConformanceResponse_set_serialize_error(
+ response, upb_strview_make(msg, sizeof(msg)));
+ return;
+ }
+ conformance_ConformanceResponse_set_protobuf_payload(
+ response, upb_strview_make(serialized, serialized_len));
+ break;
+ }
+
+ default: {
+ static const char msg[] = "Unsupported output format.";
+ conformance_ConformanceResponse_set_skipped(
+ response, upb_strview_make(msg, sizeof(msg)));
+ return;
+ }
+ }
+
+ return;
+}
+
+bool DoTestIo(void) {
+ upb_arena *arena;
+ upb_alloc *alloc;
+ upb_status status;
+ char *serialized_input;
+ char *serialized_output;
+ uint32_t input_size;
+ size_t output_size;
+ conformance_ConformanceRequest *request;
+ conformance_ConformanceResponse *response;
+
+ if (!CheckedRead(STDIN_FILENO, &input_size, sizeof(uint32_t))) {
+ /* EOF. */
+ return false;
+ }
+
+ arena = upb_arena_new();
+ alloc = upb_arena_alloc(arena);
+ serialized_input = upb_malloc(alloc, input_size);
+
+ if (!CheckedRead(STDIN_FILENO, serialized_input, input_size)) {
+ fprintf(stderr, "conformance_upb: unexpected EOF on stdin.\n");
+ exit(1);
+ }
+
+ request =
+ conformance_ConformanceRequest_parse(serialized_input, input_size, arena);
+ response = conformance_ConformanceResponse_new(arena);
+
+ if (request) {
+ DoTest(request, response, arena);
+ } else {
+ fprintf(stderr, "conformance_upb: parse of ConformanceRequest failed: %s\n",
+ upb_status_errmsg(&status));
+ }
+
+ serialized_output = conformance_ConformanceResponse_serialize(
+ response, arena, &output_size);
+
+ CheckedWrite(STDOUT_FILENO, &output_size, sizeof(uint32_t));
+ CheckedWrite(STDOUT_FILENO, serialized_output, output_size);
+
+ test_count++;
+
+ upb_arena_free(arena);
+
+ return true;
+}
+
+int main(void) {
+ while (1) {
+ if (!DoTestIo()) {
+ fprintf(stderr, "conformance_upb: received EOF from test runner "
+ "after %d tests, exiting\n", test_count);
+ return 0;
+ }
+ }
+}
diff --git a/third_party/upb/tests/conformance_upb_failures.txt b/third_party/upb/tests/conformance_upb_failures.txt
new file mode 100644
index 00000000000..05aab585e77
--- /dev/null
+++ b/third_party/upb/tests/conformance_upb_failures.txt
@@ -0,0 +1 @@
+Required.ProtobufInput.PrematureEofInSubmessageValue.MESSAGE
diff --git a/third_party/upb/tests/corpus/README b/third_party/upb/tests/corpus/README
new file mode 100644
index 00000000000..9bd8f1e93d6
--- /dev/null
+++ b/third_party/upb/tests/corpus/README
@@ -0,0 +1 @@
+Corpus folder for fuzzing
diff --git a/third_party/upb/tests/corpus/temp.cc b/third_party/upb/tests/corpus/temp.cc
new file mode 100644
index 00000000000..2bf1160ce69
--- /dev/null
+++ b/third_party/upb/tests/corpus/temp.cc
@@ -0,0 +1 @@
+// Hello World
diff --git a/third_party/upb/tests/file_descriptor_parsenew_fuzzer.cc b/third_party/upb/tests/file_descriptor_parsenew_fuzzer.cc
new file mode 100644
index 00000000000..057e62d8bf8
--- /dev/null
+++ b/third_party/upb/tests/file_descriptor_parsenew_fuzzer.cc
@@ -0,0 +1,15 @@
+#include
+
+#include "google/protobuf/descriptor.upb.h"
+#include "upb/upb.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ upb::Arena arena;
+ google_protobuf_FileDescriptorProto_parse(reinterpret_cast(data),
+ size, arena.ptr());
+ return 0;
+}
+
+#ifndef HAVE_FUZZER
+int main() {}
+#endif
diff --git a/third_party/upb/tests/google_message1.dat b/third_party/upb/tests/google_message1.dat
new file mode 100644
index 00000000000..bc0f064cc2e
Binary files /dev/null and b/third_party/upb/tests/google_message1.dat differ
diff --git a/third_party/upb/tests/google_message2.dat b/third_party/upb/tests/google_message2.dat
new file mode 100644
index 00000000000..06c09441b9e
Binary files /dev/null and b/third_party/upb/tests/google_message2.dat differ
diff --git a/third_party/upb/tests/google_messages.proto b/third_party/upb/tests/google_messages.proto
new file mode 100644
index 00000000000..489c4707327
--- /dev/null
+++ b/third_party/upb/tests/google_messages.proto
@@ -0,0 +1,149 @@
+
+package benchmarks;
+
+option optimize_for = SPEED;
+
+enum Foo {
+ FOO_VALUE = 1;
+ FOO_VALUE2 = 2;
+}
+
+message Simple {
+ message M2 {
+ optional int32 f1 = 1234567;
+ }
+ optional M2 m2 = 1;
+}
+
+message SpeedMessage1 {
+ required string field1 = 1;
+ optional string field9 = 9;
+ optional string field18 = 18;
+ optional bool field80 = 80 [default=false];
+ optional bool field81 = 81 [default=true];
+ required int32 field2 = 2;
+ required int32 field3 = 3;
+ optional int32 field280 = 280;
+ optional int32 field6 = 6 [default=0];
+ optional int64 field22 = 22;
+ optional string field4 = 4;
+ repeated fixed64 field5 = 5;
+ optional bool field59 = 59 [default=false];
+ optional string field7 = 7;
+ optional int32 field16 = 16;
+ optional int32 field130 = 130 [default=0];
+ optional bool field12 = 12 [default=true];
+ optional bool field17 = 17 [default=true];
+ optional bool field13 = 13 [default=true];
+ optional bool field14 = 14 [default=true];
+ optional int32 field104 = 104 [default=0];
+ optional int32 field100 = 100 [default=0];
+ optional int32 field101 = 101 [default=0];
+ optional string field102 = 102;
+ optional string field103 = 103;
+ optional int32 field29 = 29 [default=0];
+ optional bool field30 = 30 [default=false];
+ optional int32 field60 = 60 [default=-1];
+ optional int32 field271 = 271 [default=-1];
+ optional int32 field272 = 272 [default=-1];
+ optional int32 field150 = 150;
+ optional int32 field23 = 23 [default=0];
+ optional bool field24 = 24 [default=false];
+ optional int32 field25 = 25 [default=0];
+ optional SpeedMessage1SubMessage field15 = 15;
+ optional bool field78 = 78;
+ optional int32 field67 = 67 [default=0];
+ optional int32 field68 = 68;
+ optional int32 field128 = 128 [default=0];
+ optional string field129 = 129 [default="xxxxxxxxxxxxxxxxxxxxx"];
+ optional int32 field131 = 131 [default=0];
+ optional Foo field132 = 132 [default=FOO_VALUE];
+}
+
+message SpeedMessage1SubMessage {
+ optional int32 field1 = 1 [default=0];
+ optional int32 field2 = 2 [default=0];
+ optional int32 field3 = 3 [default=0];
+ optional string field15 = 15 [default="FOOBAR!"];
+ optional bool field12 = 12 [default=true];
+ optional int64 field13 = 13;
+ optional int64 field14 = 14;
+ optional int32 field16 = 16;
+ optional int32 field19 = 19 [default=2];
+ optional bool field20 = 20 [default=true];
+ optional bool field28 = 28 [default=true];
+ optional fixed64 field21 = 21;
+ optional int32 field22 = 22;
+ optional bool field23 = 23 [ default=false ];
+ optional bool field206 = 206 [default=false];
+ optional fixed32 field203 = 203;
+ optional int32 field204 = 204;
+ optional string field205 = 205;
+ optional uint64 field207 = 207;
+ optional uint64 field300 = 300;
+}
+
+message SpeedMessage2 {
+ optional string field1 = 1;
+ optional int64 field3 = 3;
+ optional int64 field4 = 4;
+ optional int64 field30 = 30;
+ optional bool field75 = 75 [default=false];
+ optional string field6 = 6;
+ optional bytes field2 = 2;
+ optional int32 field21 = 21 [default=0];
+ optional int32 field71 = 71;
+ optional float field25 = 25;
+ optional int32 field109 = 109 [default=0];
+ optional int32 field210 = 210 [default=0];
+ optional int32 field211 = 211 [default=0];
+ optional int32 field212 = 212 [default=0];
+ optional int32 field213 = 213 [default=0];
+ optional int32 field216 = 216 [default=0];
+ optional int32 field217 = 217 [default=0];
+ optional int32 field218 = 218 [default=0];
+ optional int32 field220 = 220 [default=0];
+ optional int32 field221 = 221 [default=0];
+ optional float field222 = 222 [default=0.0];
+ optional int32 field63 = 63;
+
+ repeated group Group1 = 10 {
+ required float field11 = 11;
+ optional float field26 = 26;
+ optional string field12 = 12;
+ optional string field13 = 13;
+ repeated string field14 = 14;
+ required uint64 field15 = 15;
+ optional int32 field5 = 5;
+ optional string field27 = 27;
+ optional int32 field28 = 28;
+ optional string field29 = 29;
+ optional string field16 = 16;
+ repeated string field22 = 22;
+ repeated int32 field73 = 73;
+ optional int32 field20 = 20 [default=0];
+ optional string field24 = 24;
+ optional SpeedMessage2GroupedMessage field31 = 31;
+ }
+ repeated string field128 = 128;
+ optional int64 field131 = 131;
+ repeated string field127 = 127;
+ optional int32 field129 = 129;
+ repeated int64 field130 = 130;
+ optional bool field205 = 205 [default=false];
+ optional bool field206 = 206 [default=false];
+}
+
+message SpeedMessage2GroupedMessage {
+ optional float field1 = 1;
+ optional float field2 = 2;
+ optional float field3 = 3 [default=0.0];
+ optional bool field4 = 4;
+ optional bool field5 = 5;
+ optional bool field6 = 6 [default=true];
+ optional bool field7 = 7 [default=false];
+ optional float field8 = 8;
+ optional bool field9 = 9;
+ optional float field10 = 10;
+ optional int64 field11 = 11;
+}
diff --git a/third_party/upb/tests/json/enum_from_separate_file.proto b/third_party/upb/tests/json/enum_from_separate_file.proto
new file mode 100644
index 00000000000..ceb9b42aa1c
--- /dev/null
+++ b/third_party/upb/tests/json/enum_from_separate_file.proto
@@ -0,0 +1,9 @@
+syntax = "proto2";
+
+import "tests/json/test.proto";
+
+package upb.test.json;
+
+message ImportEnum {
+ optional MyEnum e = 1;
+}
diff --git a/third_party/upb/tests/json/test.proto b/third_party/upb/tests/json/test.proto
new file mode 100644
index 00000000000..2db0388d778
--- /dev/null
+++ b/third_party/upb/tests/json/test.proto
@@ -0,0 +1,47 @@
+syntax = "proto3";
+
+package upb.test.json;
+
+message TestMessage {
+ int32 optional_int32 = 1;
+ int64 optional_int64 = 2;
+ int32 optional_uint32 = 3;
+ int64 optional_uint64 = 4;
+ string optional_string = 5;
+ bytes optional_bytes = 6;
+ bool optional_bool = 7;
+ SubMessage optional_msg = 8;
+ MyEnum optional_enum = 9;
+
+ repeated int32 repeated_int32 = 11;
+ repeated int64 repeated_int64 = 12;
+ repeated uint32 repeated_uint32 = 13;
+ repeated uint64 repeated_uint64 = 14;
+ repeated string repeated_string = 15;
+ repeated bytes repeated_bytes = 16;
+ repeated bool repeated_bool = 17;
+ repeated SubMessage repeated_msg = 18;
+ repeated MyEnum repeated_enum = 19;
+
+ map map_string_string = 20;
+ map map_int32_string = 21;
+ map map_bool_string = 22;
+ map map_string_int32 = 23;
+ map map_string_bool = 24;
+ map map_string_msg = 25;
+
+ oneof o {
+ int32 oneof_int32 = 26;
+ int64 oneof_int64 = 27;
+ }
+}
+
+message SubMessage {
+ int32 foo = 1;
+}
+
+enum MyEnum {
+ A = 0;
+ B = 1;
+ C = 2;
+}
diff --git a/third_party/upb/tests/json/test.proto.pb b/third_party/upb/tests/json/test.proto.pb
new file mode 100644
index 00000000000..94b8b92e616
Binary files /dev/null and b/third_party/upb/tests/json/test.proto.pb differ
diff --git a/third_party/upb/tests/json/test_json.cc b/third_party/upb/tests/json/test_json.cc
new file mode 100644
index 00000000000..66508179b3f
--- /dev/null
+++ b/third_party/upb/tests/json/test_json.cc
@@ -0,0 +1,256 @@
+/*
+ *
+ * A set of tests for JSON parsing and serialization.
+ */
+
+#include "tests/json/test.upbdefs.h"
+#include "tests/json/test.upb.h" // Test that it compiles for C++.
+#include "tests/test_util.h"
+#include "tests/upb_test.h"
+#include "upb/handlers.h"
+#include "upb/json/parser.h"
+#include "upb/json/printer.h"
+#include "upb/upb.h"
+
+#include
+
+#include "upb/port_def.inc"
+
+// Macros for readability in test case list: allows us to give TEST("...") /
+// EXPECT("...") pairs.
+#define TEST(x) x
+#define EXPECT_SAME NULL
+#define EXPECT(x) x
+#define TEST_SENTINEL { NULL, NULL }
+
+struct TestCase {
+ const char* input;
+ const char* expected;
+};
+
+bool verbose = false;
+
+static TestCase kTestRoundtripMessages[] = {
+ // Test most fields here.
+ {
+ TEST("{\"optionalInt32\":-42,\"optionalString\":\"Test\\u0001Message\","
+ "\"optionalMsg\":{\"foo\":42},"
+ "\"optionalBool\":true,\"repeatedMsg\":[{\"foo\":1},"
+ "{\"foo\":2}]}"),
+ EXPECT_SAME
+ },
+ // We must also recognize raw proto names.
+ {
+ TEST("{\"optional_int32\":-42,\"optional_string\":\"Test\\u0001Message\","
+ "\"optional_msg\":{\"foo\":42},"
+ "\"optional_bool\":true,\"repeated_msg\":[{\"foo\":1},"
+ "{\"foo\":2}]}"),
+ EXPECT("{\"optionalInt32\":-42,\"optionalString\":\"Test\\u0001Message\","
+ "\"optionalMsg\":{\"foo\":42},"
+ "\"optionalBool\":true,\"repeatedMsg\":[{\"foo\":1},"
+ "{\"foo\":2}]}")
+ },
+ // Test special escapes in strings.
+ {
+ TEST("{\"repeatedString\":[\"\\b\",\"\\r\",\"\\n\",\"\\f\",\"\\t\","
+ "\"\uFFFF\"]}"),
+ EXPECT_SAME
+ },
+ // Test enum symbolic names.
+ {
+ // The common case: parse and print the symbolic name.
+ TEST("{\"optionalEnum\":\"A\"}"),
+ EXPECT_SAME
+ },
+ {
+ // Unknown enum value: will be printed as an integer.
+ TEST("{\"optionalEnum\":42}"),
+ EXPECT_SAME
+ },
+ {
+ // Known enum value: we're happy to parse an integer but we will re-emit the
+ // symbolic name.
+ TEST("{\"optionalEnum\":1}"),
+ EXPECT("{\"optionalEnum\":\"B\"}")
+ },
+ // UTF-8 tests: escapes -> literal UTF8 in output.
+ {
+ // Note double escape on \uXXXX: we want the escape to be processed by the
+ // JSON parser, not by the C++ compiler!
+ TEST("{\"optionalString\":\"\\u007F\"}"),
+ EXPECT("{\"optionalString\":\"\x7F\"}")
+ },
+ {
+ TEST("{\"optionalString\":\"\\u0080\"}"),
+ EXPECT("{\"optionalString\":\"\xC2\x80\"}")
+ },
+ {
+ TEST("{\"optionalString\":\"\\u07FF\"}"),
+ EXPECT("{\"optionalString\":\"\xDF\xBF\"}")
+ },
+ {
+ TEST("{\"optionalString\":\"\\u0800\"}"),
+ EXPECT("{\"optionalString\":\"\xE0\xA0\x80\"}")
+ },
+ {
+ TEST("{\"optionalString\":\"\\uFFFF\"}"),
+ EXPECT("{\"optionalString\":\"\xEF\xBF\xBF\"}")
+ },
+ // map-field tests
+ {
+ TEST("{\"mapStringString\":{\"a\":\"value1\",\"b\":\"value2\","
+ "\"c\":\"value3\"}}"),
+ EXPECT_SAME
+ },
+ {
+ TEST("{\"mapInt32String\":{\"1\":\"value1\",\"-1\":\"value2\","
+ "\"1234\":\"value3\"}}"),
+ EXPECT_SAME
+ },
+ {
+ TEST("{\"mapBoolString\":{\"false\":\"value1\",\"true\":\"value2\"}}"),
+ EXPECT_SAME
+ },
+ {
+ TEST("{\"mapStringInt32\":{\"asdf\":1234,\"jkl;\":-1}}"),
+ EXPECT_SAME
+ },
+ {
+ TEST("{\"mapStringBool\":{\"asdf\":true,\"jkl;\":false}}"),
+ EXPECT_SAME
+ },
+ {
+ TEST("{\"mapStringMsg\":{\"asdf\":{\"foo\":42},\"jkl;\":{\"foo\":84}}}"),
+ EXPECT_SAME
+ },
+ TEST_SENTINEL
+};
+
+static TestCase kTestRoundtripMessagesPreserve[] = {
+ // Test most fields here.
+ {
+ TEST("{\"optional_int32\":-42,\"optional_string\":\"Test\\u0001Message\","
+ "\"optional_msg\":{\"foo\":42},"
+ "\"optional_bool\":true,\"repeated_msg\":[{\"foo\":1},"
+ "{\"foo\":2}]}"),
+ EXPECT_SAME
+ },
+ TEST_SENTINEL
+};
+
+class StringSink {
+ public:
+ StringSink() {
+ upb_byteshandler_init(&byteshandler_);
+ upb_byteshandler_setstring(&byteshandler_, &str_handler, NULL);
+ upb_bytessink_reset(&bytessink_, &byteshandler_, &s_);
+ }
+ ~StringSink() { }
+
+ upb_bytessink Sink() { return bytessink_; }
+
+ const std::string& Data() { return s_; }
+
+ private:
+
+ static size_t str_handler(void* _closure, const void* hd,
+ const char* data, size_t len,
+ const upb_bufhandle* handle) {
+ UPB_UNUSED(hd);
+ UPB_UNUSED(handle);
+ std::string* s = static_cast(_closure);
+ std::string appended(data, len);
+ s->append(data, len);
+ return len;
+ }
+
+ upb_byteshandler byteshandler_;
+ upb_bytessink bytessink_;
+ std::string s_;
+};
+
+void test_json_roundtrip_message(const char* json_src,
+ const char* json_expected,
+ const upb::Handlers* serialize_handlers,
+ const upb::json::ParserMethodPtr parser_method,
+ int seam) {
+ VerboseParserEnvironment env(verbose);
+ StringSink data_sink;
+ upb::json::PrinterPtr printer = upb::json::PrinterPtr::Create(
+ env.arena(), serialize_handlers, data_sink.Sink());
+ upb::json::ParserPtr parser = upb::json::ParserPtr::Create(
+ env.arena(), parser_method, NULL, printer.input(), env.status(), false);
+ env.ResetBytesSink(parser.input());
+ env.Reset(json_src, strlen(json_src), false, false);
+
+ bool ok = env.Start() &&
+ env.ParseBuffer(seam) &&
+ env.ParseBuffer(-1) &&
+ env.End();
+
+ ASSERT(ok);
+ ASSERT(env.CheckConsistency());
+
+ if (memcmp(json_expected,
+ data_sink.Data().data(),
+ data_sink.Data().size())) {
+ fprintf(stderr,
+ "JSON parse/serialize roundtrip result differs:\n"
+ "Original:\n%s\nParsed/Serialized:\n%s\n",
+ json_src, data_sink.Data().c_str());
+ abort();
+ }
+}
+
+// Starts with a message in JSON format, parses and directly serializes again,
+// and compares the result.
+void test_json_roundtrip() {
+ upb::SymbolTable symtab;
+ upb::HandlerCache serialize_handlercache(
+ upb::json::PrinterPtr::NewCache(false));
+ upb::json::CodeCache parse_codecache;
+
+ upb::MessageDefPtr md(upb_test_json_TestMessage_getmsgdef(symtab.ptr()));
+ ASSERT(md);
+ const upb::Handlers* serialize_handlers = serialize_handlercache.Get(md);
+ const upb::json::ParserMethodPtr parser_method = parse_codecache.Get(md);
+ ASSERT(serialize_handlers);
+
+ for (const TestCase* test_case = kTestRoundtripMessages;
+ test_case->input != NULL; test_case++) {
+ const char *expected =
+ (test_case->expected == EXPECT_SAME) ?
+ test_case->input :
+ test_case->expected;
+
+ for (size_t i = 0; i < strlen(test_case->input); i++) {
+ test_json_roundtrip_message(test_case->input, expected,
+ serialize_handlers, parser_method, i);
+ }
+ }
+
+ serialize_handlercache = upb::json::PrinterPtr::NewCache(true);
+ serialize_handlers = serialize_handlercache.Get(md);
+
+ for (const TestCase* test_case = kTestRoundtripMessagesPreserve;
+ test_case->input != NULL; test_case++) {
+ const char *expected =
+ (test_case->expected == EXPECT_SAME) ?
+ test_case->input :
+ test_case->expected;
+
+ for (size_t i = 0; i < strlen(test_case->input); i++) {
+ test_json_roundtrip_message(test_case->input, expected,
+ serialize_handlers, parser_method, i);
+ }
+ }
+}
+
+extern "C" {
+int run_tests(int argc, char *argv[]) {
+ UPB_UNUSED(argc);
+ UPB_UNUSED(argv);
+ test_json_roundtrip();
+ return 0;
+}
+}
diff --git a/third_party/upb/tests/pb/test_decoder.cc b/third_party/upb/tests/pb/test_decoder.cc
new file mode 100644
index 00000000000..5cc59e40c92
--- /dev/null
+++ b/third_party/upb/tests/pb/test_decoder.cc
@@ -0,0 +1,1203 @@
+/*
+ *
+ * An exhaustive set of tests for parsing both valid and invalid protobuf
+ * input, with buffer breaks in arbitrary places.
+ *
+ * Tests to add:
+ * - string/bytes
+ * - unknown field handler called appropriately
+ * - unknown fields can be inserted in random places
+ * - fuzzing of valid input
+ * - resource limits (max stack depth, max string len)
+ * - testing of groups
+ * - more throrough testing of sequences
+ * - test skipping of submessages
+ * - test suspending the decoder
+ * - buffers that are close enough to the end of the address space that
+ * pointers overflow (this might be difficult).
+ * - a few "kitchen sink" examples (one proto that uses all types, lots
+ * of submsg/sequences, etc.
+ * - test different handlers at every level and whether handlers fire at
+ * the correct field path.
+ * - test skips that extend past the end of current buffer (where decoder
+ * returns value greater than the size param).
+ */
+
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS // For PRIuS, etc.
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "tests/test_util.h"
+#include "tests/upb_test.h"
+#include "tests/pb/test_decoder.upbdefs.h"
+
+#ifdef AMALGAMATED
+#include "upb.h"
+#else // AMALGAMATED
+#include "upb/handlers.h"
+#include "upb/pb/decoder.h"
+#include "upb/pb/varint.int.h"
+#include "upb/upb.h"
+#endif // !AMALGAMATED
+
+#include "upb/port_def.inc"
+
+#undef PRINT_FAILURE
+#define PRINT_FAILURE(expr) \
+ fprintf(stderr, "Assertion failed: %s:%d\n", __FILE__, __LINE__); \
+ fprintf(stderr, "expr: %s\n", #expr); \
+ if (testhash) { \
+ fprintf(stderr, "assertion failed running test %x.\n", testhash); \
+ if (!filter_hash) { \
+ fprintf(stderr, \
+ "Run with the arg %x to run only this test. " \
+ "(This will also turn on extra debugging output)\n", \
+ testhash); \
+ } \
+ fprintf(stderr, "Failed at %02.2f%% through tests.\n", \
+ (float)completed * 100 / total); \
+ }
+
+#define MAX_NESTING 64
+
+#define LINE(x) x "\n"
+
+uint32_t filter_hash = 0;
+double completed;
+double total;
+double *count;
+
+enum TestMode {
+ COUNT_ONLY = 1,
+ NO_HANDLERS = 2,
+ ALL_HANDLERS = 3
+} test_mode;
+
+// Copied from decoder.c, since this is not a public interface.
+typedef struct {
+ uint8_t native_wire_type;
+ bool is_numeric;
+} upb_decoder_typeinfo;
+
+static const upb_decoder_typeinfo upb_decoder_types[] = {
+ {UPB_WIRE_TYPE_END_GROUP, false}, // ENDGROUP
+ {UPB_WIRE_TYPE_64BIT, true}, // DOUBLE
+ {UPB_WIRE_TYPE_32BIT, true}, // FLOAT
+ {UPB_WIRE_TYPE_VARINT, true}, // INT64
+ {UPB_WIRE_TYPE_VARINT, true}, // UINT64
+ {UPB_WIRE_TYPE_VARINT, true}, // INT32
+ {UPB_WIRE_TYPE_64BIT, true}, // FIXED64
+ {UPB_WIRE_TYPE_32BIT, true}, // FIXED32
+ {UPB_WIRE_TYPE_VARINT, true}, // BOOL
+ {UPB_WIRE_TYPE_DELIMITED, false}, // STRING
+ {UPB_WIRE_TYPE_START_GROUP, false}, // GROUP
+ {UPB_WIRE_TYPE_DELIMITED, false}, // MESSAGE
+ {UPB_WIRE_TYPE_DELIMITED, false}, // BYTES
+ {UPB_WIRE_TYPE_VARINT, true}, // UINT32
+ {UPB_WIRE_TYPE_VARINT, true}, // ENUM
+ {UPB_WIRE_TYPE_32BIT, true}, // SFIXED32
+ {UPB_WIRE_TYPE_64BIT, true}, // SFIXED64
+ {UPB_WIRE_TYPE_VARINT, true}, // SINT32
+ {UPB_WIRE_TYPE_VARINT, true}, // SINT64
+};
+
+#ifndef USE_GOOGLE
+using std::string;
+#endif
+
+void vappendf(string* str, const char *format, va_list args) {
+ va_list copy;
+ _upb_va_copy(copy, args);
+
+ int count = vsnprintf(NULL, 0, format, args);
+ if (count >= 0)
+ {
+ UPB_ASSERT(count < 32768);
+ char *buffer = new char[count + 1];
+ UPB_ASSERT(buffer);
+ count = vsnprintf(buffer, count + 1, format, copy);
+ UPB_ASSERT(count >= 0);
+ str->append(buffer, count);
+ delete [] buffer;
+ }
+ va_end(copy);
+}
+
+void appendf(string* str, const char *fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ vappendf(str, fmt, args);
+ va_end(args);
+}
+
+void PrintBinary(const string& str) {
+ for (size_t i = 0; i < str.size(); i++) {
+ if (isprint(str[i])) {
+ fprintf(stderr, "%c", str[i]);
+ } else {
+ fprintf(stderr, "\\x%02x", (int)(uint8_t)str[i]);
+ }
+ }
+}
+
+/* Routines for building arbitrary protos *************************************/
+
+const string empty;
+
+string cat(const string& a, const string& b,
+ const string& c = empty,
+ const string& d = empty,
+ const string& e = empty,
+ const string& f = empty,
+ const string& g = empty,
+ const string& h = empty,
+ const string& i = empty,
+ const string& j = empty,
+ const string& k = empty,
+ const string& l = empty) {
+ string ret;
+ ret.reserve(a.size() + b.size() + c.size() + d.size() + e.size() + f.size() +
+ g.size() + h.size() + i.size() + j.size() + k.size() + l.size());
+ ret.append(a);
+ ret.append(b);
+ ret.append(c);
+ ret.append(d);
+ ret.append(e);
+ ret.append(f);
+ ret.append(g);
+ ret.append(h);
+ ret.append(i);
+ ret.append(j);
+ ret.append(k);
+ ret.append(l);
+ return ret;
+}
+
+template
+string num2string(T num) {
+ std::ostringstream ss;
+ ss << num;
+ return ss.str();
+}
+
+string varint(uint64_t x) {
+ char buf[UPB_PB_VARINT_MAX_LEN];
+ size_t len = upb_vencode64(x, buf);
+ return string(buf, len);
+}
+
+// TODO: proper byte-swapping for big-endian machines.
+string fixed32(void *data) { return string(static_cast(data), 4); }
+string fixed64(void *data) { return string(static_cast(data), 8); }
+
+string delim(const string& buf) { return cat(varint(buf.size()), buf); }
+string uint32(uint32_t u32) { return fixed32(&u32); }
+string uint64(uint64_t u64) { return fixed64(&u64); }
+string flt(float f) { return fixed32(&f); }
+string dbl(double d) { return fixed64(&d); }
+string zz32(int32_t x) { return varint(upb_zzenc_32(x)); }
+string zz64(int64_t x) { return varint(upb_zzenc_64(x)); }
+
+string tag(uint32_t fieldnum, char wire_type) {
+ return varint((fieldnum << 3) | wire_type);
+}
+
+string submsg(uint32_t fn, const string& buf) {
+ return cat( tag(fn, UPB_WIRE_TYPE_DELIMITED), delim(buf) );
+}
+
+string group(uint32_t fn, const string& buf) {
+ return cat(tag(fn, UPB_WIRE_TYPE_START_GROUP), buf,
+ tag(fn, UPB_WIRE_TYPE_END_GROUP));
+}
+
+// Like delim()/submsg(), but intentionally encodes an incorrect length.
+// These help test when a delimited boundary doesn't land in the right place.
+string badlen_delim(int err, const string& buf) {
+ return cat(varint(buf.size() + err), buf);
+}
+
+string badlen_submsg(int err, uint32_t fn, const string& buf) {
+ return cat( tag(fn, UPB_WIRE_TYPE_DELIMITED), badlen_delim(err, buf) );
+}
+
+
+/* A set of handlers that covers all .proto types *****************************/
+
+// The handlers simply append to a string indicating what handlers were called.
+// This string is similar to protobuf text format but fields are referred to by
+// number instead of name and sequences are explicitly delimited. We indent
+// using the closure depth to test that the stack of closures is properly
+// handled.
+
+int closures[MAX_NESTING];
+string output;
+
+void indentbuf(string *buf, int depth) {
+ buf->append(2 * depth, ' ');
+}
+
+#define NUMERIC_VALUE_HANDLER(member, ctype, fmt) \
+ bool value_##member(int* depth, const uint32_t* num, ctype val) { \
+ indentbuf(&output, *depth); \
+ appendf(&output, "%" PRIu32 ":%" fmt "\n", *num, val); \
+ return true; \
+ }
+
+NUMERIC_VALUE_HANDLER(uint32, uint32_t, PRIu32)
+NUMERIC_VALUE_HANDLER(uint64, uint64_t, PRIu64)
+NUMERIC_VALUE_HANDLER(int32, int32_t, PRId32)
+NUMERIC_VALUE_HANDLER(int64, int64_t, PRId64)
+NUMERIC_VALUE_HANDLER(float, float, "g")
+NUMERIC_VALUE_HANDLER(double, double, "g")
+
+bool value_bool(int* depth, const uint32_t* num, bool val) {
+ indentbuf(&output, *depth);
+ appendf(&output, "%" PRIu32 ":%s\n", *num, val ? "true" : "false");
+ return true;
+}
+
+int* startstr(int* depth, const uint32_t* num, size_t size_hint) {
+ indentbuf(&output, *depth);
+ appendf(&output, "%" PRIu32 ":(%zu)\"", *num, size_hint);
+ return depth + 1;
+}
+
+size_t value_string(int* depth, const uint32_t* num, const char* buf,
+ size_t n, const upb_bufhandle* handle) {
+ UPB_UNUSED(num);
+ UPB_UNUSED(depth);
+ output.append(buf, n);
+ ASSERT(handle == &global_handle);
+ return n;
+}
+
+bool endstr(int* depth, const uint32_t* num) {
+ UPB_UNUSED(num);
+ output.append("\n");
+ indentbuf(&output, *depth);
+ appendf(&output, "%" PRIu32 ":\"\n", *num);
+ return true;
+}
+
+int* startsubmsg(int* depth, const uint32_t* num) {
+ indentbuf(&output, *depth);
+ appendf(&output, "%" PRIu32 ":{\n", *num);
+ return depth + 1;
+}
+
+bool endsubmsg(int* depth, const uint32_t* num) {
+ UPB_UNUSED(num);
+ indentbuf(&output, *depth);
+ output.append("}\n");
+ return true;
+}
+
+int* startseq(int* depth, const uint32_t* num) {
+ indentbuf(&output, *depth);
+ appendf(&output, "%" PRIu32 ":[\n", *num);
+ return depth + 1;
+}
+
+bool endseq(int* depth, const uint32_t* num) {
+ UPB_UNUSED(num);
+ indentbuf(&output, *depth);
+ output.append("]\n");
+ return true;
+}
+
+bool startmsg(int* depth) {
+ indentbuf(&output, *depth);
+ output.append("<\n");
+ return true;
+}
+
+bool endmsg(int* depth, upb_status* status) {
+ UPB_UNUSED(status);
+ indentbuf(&output, *depth);
+ output.append(">\n");
+ return true;
+}
+
+void free_uint32(void *val) {
+ uint32_t *u32 = static_cast(val);
+ delete u32;
+}
+
+template
+void doreg(upb::HandlersPtr h, uint32_t num) {
+ upb::FieldDefPtr f = h.message_def().FindFieldByNumber(num);
+ ASSERT(f);
+ ASSERT(h.SetValueHandler(f, UpbBind(F, new uint32_t(num))));
+ if (f.IsSequence()) {
+ ASSERT(h.SetStartSequenceHandler(f, UpbBind(startseq, new uint32_t(num))));
+ ASSERT(h.SetEndSequenceHandler(f, UpbBind(endseq, new uint32_t(num))));
+ }
+}
+
+// The repeated field number to correspond to the given non-repeated field
+// number.
+uint32_t rep_fn(uint32_t fn) {
+ return (UPB_MAX_FIELDNUMBER - 1000) + fn;
+}
+
+#define NOP_FIELD 40
+#define UNKNOWN_FIELD 666
+
+template
+void reg(upb::HandlersPtr h, upb_descriptortype_t type) {
+ // We register both a repeated and a non-repeated field for every type.
+ // For the non-repeated field we make the field number the same as the
+ // type. For the repeated field we make it a function of the type.
+ doreg(h, type);
+ doreg(h, rep_fn(type));
+}
+
+void regseq(upb::HandlersPtr h, upb::FieldDefPtr f, uint32_t num) {
+ ASSERT(h.SetStartSequenceHandler(f, UpbBind(startseq, new uint32_t(num))));
+ ASSERT(h.SetEndSequenceHandler(f, UpbBind(endseq, new uint32_t(num))));
+}
+
+void reg_subm(upb::HandlersPtr h, uint32_t num) {
+ upb::FieldDefPtr f = h.message_def().FindFieldByNumber(num);
+ ASSERT(f);
+ if (f.IsSequence()) regseq(h, f, num);
+ ASSERT(
+ h.SetStartSubMessageHandler(f, UpbBind(startsubmsg, new uint32_t(num))));
+ ASSERT(h.SetEndSubMessageHandler(f, UpbBind(endsubmsg, new uint32_t(num))));
+}
+
+void reg_str(upb::HandlersPtr h, uint32_t num) {
+ upb::FieldDefPtr f = h.message_def().FindFieldByNumber(num);
+ ASSERT(f);
+ if (f.IsSequence()) regseq(h, f, num);
+ ASSERT(h.SetStartStringHandler(f, UpbBind(startstr, new uint32_t(num))));
+ ASSERT(h.SetEndStringHandler(f, UpbBind(endstr, new uint32_t(num))));
+ ASSERT(h.SetStringHandler(f, UpbBind(value_string, new uint32_t(num))));
+}
+
+struct HandlerRegisterData {
+ TestMode mode;
+};
+
+void callback(const void *closure, upb::Handlers* h_ptr) {
+ upb::HandlersPtr h(h_ptr);
+ const HandlerRegisterData* data =
+ static_cast(closure);
+ if (data->mode == ALL_HANDLERS) {
+ h.SetStartMessageHandler(UpbMakeHandler(startmsg));
+ h.SetEndMessageHandler(UpbMakeHandler(endmsg));
+
+ // Register handlers for each type.
+ reg(h, UPB_DESCRIPTOR_TYPE_DOUBLE);
+ reg (h, UPB_DESCRIPTOR_TYPE_FLOAT);
+ reg (h, UPB_DESCRIPTOR_TYPE_INT64);
+ reg(h, UPB_DESCRIPTOR_TYPE_UINT64);
+ reg (h, UPB_DESCRIPTOR_TYPE_INT32);
+ reg(h, UPB_DESCRIPTOR_TYPE_FIXED64);
+ reg(h, UPB_DESCRIPTOR_TYPE_FIXED32);
+ reg (h, UPB_DESCRIPTOR_TYPE_BOOL);
+ reg(h, UPB_DESCRIPTOR_TYPE_UINT32);
+ reg (h, UPB_DESCRIPTOR_TYPE_ENUM);
+ reg (h, UPB_DESCRIPTOR_TYPE_SFIXED32);
+ reg (h, UPB_DESCRIPTOR_TYPE_SFIXED64);
+ reg (h, UPB_DESCRIPTOR_TYPE_SINT32);
+ reg (h, UPB_DESCRIPTOR_TYPE_SINT64);
+
+ reg_str(h, UPB_DESCRIPTOR_TYPE_STRING);
+ reg_str(h, UPB_DESCRIPTOR_TYPE_BYTES);
+ reg_str(h, rep_fn(UPB_DESCRIPTOR_TYPE_STRING));
+ reg_str(h, rep_fn(UPB_DESCRIPTOR_TYPE_BYTES));
+
+ // Register submessage/group handlers that are self-recursive
+ // to this type, eg: message M { optional M m = 1; }
+ reg_subm(h, UPB_DESCRIPTOR_TYPE_MESSAGE);
+ reg_subm(h, rep_fn(UPB_DESCRIPTOR_TYPE_MESSAGE));
+
+ if (h.message_def().full_name() == std::string("DecoderTest")) {
+ reg_subm(h, UPB_DESCRIPTOR_TYPE_GROUP);
+ reg_subm(h, rep_fn(UPB_DESCRIPTOR_TYPE_GROUP));
+ }
+
+ // For NOP_FIELD we register no handlers, so we can pad a proto freely without
+ // changing the output.
+ }
+}
+
+/* Running of test cases ******************************************************/
+
+const upb::Handlers *global_handlers;
+upb::pb::DecoderMethodPtr global_method;
+
+upb::pb::DecoderPtr CreateDecoder(upb::Arena* arena,
+ upb::pb::DecoderMethodPtr method,
+ upb::Sink sink, upb::Status* status) {
+ upb::pb::DecoderPtr ret =
+ upb::pb::DecoderPtr::Create(arena, method, sink, status);
+ ret.set_max_nesting(MAX_NESTING);
+ return ret;
+}
+
+uint32_t Hash(const string& proto, const string* expected_output, size_t seam1,
+ size_t seam2, bool may_skip) {
+ uint32_t hash = upb_murmur_hash2(proto.c_str(), proto.size(), 0);
+ if (expected_output)
+ hash = upb_murmur_hash2(expected_output->c_str(), expected_output->size(), hash);
+ hash = upb_murmur_hash2(&seam1, sizeof(seam1), hash);
+ hash = upb_murmur_hash2(&seam2, sizeof(seam2), hash);
+ hash = upb_murmur_hash2(&may_skip, sizeof(may_skip), hash);
+ return hash;
+}
+
+void CheckBytesParsed(upb::pb::DecoderPtr decoder, size_t ofs) {
+ // We can't have parsed more data than the decoder callback is telling us it
+ // parsed.
+ ASSERT(decoder.BytesParsed() <= ofs);
+
+ // The difference between what we've decoded and what the decoder has accepted
+ // represents the internally buffered amount. This amount should not exceed
+ // this value which comes from decoder.int.h.
+ ASSERT(ofs <= (decoder.BytesParsed() + UPB_DECODER_MAX_RESIDUAL_BYTES));
+}
+
+static bool parse(VerboseParserEnvironment* env,
+ upb::pb::DecoderPtr decoder, int bytes) {
+ CheckBytesParsed(decoder, env->ofs());
+ bool ret = env->ParseBuffer(bytes);
+ if (ret) {
+ CheckBytesParsed(decoder, env->ofs());
+ }
+
+ return ret;
+}
+
+void do_run_decoder(VerboseParserEnvironment* env, upb::pb::DecoderPtr decoder,
+ const string& proto, const string* expected_output,
+ size_t i, size_t j, bool may_skip) {
+ env->Reset(proto.c_str(), proto.size(), may_skip, expected_output == NULL);
+ decoder.Reset();
+
+ testhash = Hash(proto, expected_output, i, j, may_skip);
+ if (filter_hash && testhash != filter_hash) return;
+ if (test_mode != COUNT_ONLY) {
+ output.clear();
+
+ if (filter_hash) {
+ fprintf(stderr, "RUNNING TEST CASE, hash=%x\n", testhash);
+ fprintf(stderr, "Input (len=%u): ", (unsigned)proto.size());
+ PrintBinary(proto);
+ fprintf(stderr, "\n");
+ if (expected_output) {
+ if (test_mode == ALL_HANDLERS) {
+ fprintf(stderr, "Expected output: %s\n", expected_output->c_str());
+ } else if (test_mode == NO_HANDLERS) {
+ fprintf(stderr,
+ "No handlers are registered, BUT if they were "
+ "the expected output would be: %s\n",
+ expected_output->c_str());
+ }
+ } else {
+ fprintf(stderr, "Expected to FAIL\n");
+ }
+ }
+
+ bool ok = env->Start() &&
+ parse(env, decoder, i) &&
+ parse(env, decoder, j - i) &&
+ parse(env, decoder, -1) &&
+ env->End();
+
+ ASSERT(env->CheckConsistency());
+
+ if (test_mode == ALL_HANDLERS) {
+ if (expected_output) {
+ if (output != *expected_output) {
+ fprintf(stderr, "Text mismatch: '%s' vs '%s'\n",
+ output.c_str(), expected_output->c_str());
+ }
+ ASSERT(ok);
+ ASSERT(output == *expected_output);
+ } else {
+ if (ok) {
+ fprintf(stderr, "Didn't expect ok result, but got output: '%s'\n",
+ output.c_str());
+ }
+ ASSERT(!ok);
+ }
+ }
+ }
+ (*count)++;
+}
+
+void run_decoder(const string& proto, const string* expected_output) {
+ VerboseParserEnvironment env(filter_hash != 0);
+ upb::Sink sink(global_handlers, &closures[0]);
+ upb::pb::DecoderPtr decoder = CreateDecoder(env.arena(), global_method, sink, env.status());
+ env.ResetBytesSink(decoder.input());
+ for (size_t i = 0; i < proto.size(); i++) {
+ for (size_t j = i; j < UPB_MIN(proto.size(), i + 5); j++) {
+ do_run_decoder(&env, decoder, proto, expected_output, i, j, true);
+ if (env.SkippedWithNull()) {
+ do_run_decoder(&env, decoder, proto, expected_output, i, j, false);
+ }
+ }
+ }
+ testhash = 0;
+}
+
+const static string thirty_byte_nop = cat(
+ tag(NOP_FIELD, UPB_WIRE_TYPE_DELIMITED), delim(string(30, 'X')) );
+
+// Indents and wraps text as if it were a submessage with this field number
+string wrap_text(int32_t fn, const string& text) {
+ string wrapped_text = text;
+ size_t pos = 0;
+ string replace_with = "\n ";
+ while ((pos = wrapped_text.find("\n", pos)) != string::npos &&
+ pos != wrapped_text.size() - 1) {
+ wrapped_text.replace(pos, 1, replace_with);
+ pos += replace_with.size();
+ }
+ wrapped_text = cat(
+ LINE("<"),
+ num2string(fn), LINE(":{")
+ " ", wrapped_text,
+ LINE("}")
+ LINE(">"));
+ return wrapped_text;
+}
+
+void assert_successful_parse(const string& proto,
+ const char *expected_fmt, ...) {
+ string expected_text;
+ va_list args;
+ va_start(args, expected_fmt);
+ vappendf(&expected_text, expected_fmt, args);
+ va_end(args);
+ // To test both middle-of-buffer and end-of-buffer code paths,
+ // repeat once with no-op padding data at the end of buffer.
+ run_decoder(proto, &expected_text);
+ run_decoder(cat( proto, thirty_byte_nop ), &expected_text);
+
+ // Test that this also works when wrapped in a submessage or group.
+ // Indent the expected text one level and wrap it.
+ string wrapped_text1 = wrap_text(UPB_DESCRIPTOR_TYPE_MESSAGE, expected_text);
+ string wrapped_text2 = wrap_text(UPB_DESCRIPTOR_TYPE_GROUP, expected_text);
+
+ run_decoder(submsg(UPB_DESCRIPTOR_TYPE_MESSAGE, proto), &wrapped_text1);
+ run_decoder(group(UPB_DESCRIPTOR_TYPE_GROUP, proto), &wrapped_text2);
+}
+
+void assert_does_not_parse_at_eof(const string& proto) {
+ run_decoder(proto, NULL);
+
+ // Also test that we fail to parse at end-of-submessage, not just
+ // end-of-message. But skip this if we have no handlers, because in that
+ // case we won't descend into the submessage.
+ if (test_mode != NO_HANDLERS) {
+ run_decoder(submsg(UPB_DESCRIPTOR_TYPE_MESSAGE, proto), NULL);
+ run_decoder(cat(submsg(UPB_DESCRIPTOR_TYPE_MESSAGE, proto),
+ thirty_byte_nop), NULL);
+ }
+}
+
+void assert_does_not_parse(const string& proto) {
+ // Test that the error is caught both at end-of-buffer and middle-of-buffer.
+ assert_does_not_parse_at_eof(proto);
+ assert_does_not_parse_at_eof(cat( proto, thirty_byte_nop ));
+}
+
+
+/* The actual tests ***********************************************************/
+
+void test_premature_eof_for_type(upb_descriptortype_t type) {
+ // Incomplete values for each wire type.
+ static const string incompletes[6] = {
+ string("\x80"), // UPB_WIRE_TYPE_VARINT
+ string("abcdefg"), // UPB_WIRE_TYPE_64BIT
+ string("\x80"), // UPB_WIRE_TYPE_DELIMITED (partial length)
+ string(), // UPB_WIRE_TYPE_START_GROUP (no value required)
+ string(), // UPB_WIRE_TYPE_END_GROUP (no value required)
+ string("abc") // UPB_WIRE_TYPE_32BIT
+ };
+
+ uint32_t fieldnum = type;
+ uint32_t rep_fieldnum = rep_fn(type);
+ int wire_type = upb_decoder_types[type].native_wire_type;
+ const string& incomplete = incompletes[wire_type];
+
+ // EOF before a known non-repeated value.
+ assert_does_not_parse_at_eof(tag(fieldnum, wire_type));
+
+ // EOF before a known repeated value.
+ assert_does_not_parse_at_eof(tag(rep_fieldnum, wire_type));
+
+ // EOF before an unknown value.
+ assert_does_not_parse_at_eof(tag(UNKNOWN_FIELD, wire_type));
+
+ // EOF inside a known non-repeated value.
+ assert_does_not_parse_at_eof(
+ cat( tag(fieldnum, wire_type), incomplete ));
+
+ // EOF inside a known repeated value.
+ assert_does_not_parse_at_eof(
+ cat( tag(rep_fieldnum, wire_type), incomplete ));
+
+ // EOF inside an unknown value.
+ assert_does_not_parse_at_eof(
+ cat( tag(UNKNOWN_FIELD, wire_type), incomplete ));
+
+ if (wire_type == UPB_WIRE_TYPE_DELIMITED) {
+ // EOF in the middle of delimited data for known non-repeated value.
+ assert_does_not_parse_at_eof(
+ cat( tag(fieldnum, wire_type), varint(1) ));
+
+ // EOF in the middle of delimited data for known repeated value.
+ assert_does_not_parse_at_eof(
+ cat( tag(rep_fieldnum, wire_type), varint(1) ));
+
+ // EOF in the middle of delimited data for unknown value.
+ assert_does_not_parse_at_eof(
+ cat( tag(UNKNOWN_FIELD, wire_type), varint(1) ));
+
+ if (type == UPB_DESCRIPTOR_TYPE_MESSAGE) {
+ // Submessage ends in the middle of a value.
+ string incomplete_submsg =
+ cat ( tag(UPB_DESCRIPTOR_TYPE_INT32, UPB_WIRE_TYPE_VARINT),
+ incompletes[UPB_WIRE_TYPE_VARINT] );
+ assert_does_not_parse(
+ cat( tag(fieldnum, UPB_WIRE_TYPE_DELIMITED),
+ varint(incomplete_submsg.size()),
+ incomplete_submsg ));
+ }
+ } else {
+ // Packed region ends in the middle of a value.
+ assert_does_not_parse(
+ cat( tag(rep_fieldnum, UPB_WIRE_TYPE_DELIMITED),
+ varint(incomplete.size()),
+ incomplete ));
+
+ // EOF in the middle of packed region.
+ assert_does_not_parse_at_eof(
+ cat( tag(rep_fieldnum, UPB_WIRE_TYPE_DELIMITED), varint(1) ));
+ }
+}
+
+// "33" and "66" are just two random values that all numeric types can
+// represent.
+void test_valid_data_for_type(upb_descriptortype_t type,
+ const string& enc33, const string& enc66) {
+ uint32_t fieldnum = type;
+ uint32_t rep_fieldnum = rep_fn(type);
+ int wire_type = upb_decoder_types[type].native_wire_type;
+
+ // Non-repeated
+ assert_successful_parse(
+ cat( tag(fieldnum, wire_type), enc33,
+ tag(fieldnum, wire_type), enc66 ),
+ LINE("<")
+ LINE("%u:33")
+ LINE("%u:66")
+ LINE(">"), fieldnum, fieldnum);
+
+ // Non-packed repeated.
+ assert_successful_parse(
+ cat( tag(rep_fieldnum, wire_type), enc33,
+ tag(rep_fieldnum, wire_type), enc66 ),
+ LINE("<")
+ LINE("%u:[")
+ LINE(" %u:33")
+ LINE(" %u:66")
+ LINE("]")
+ LINE(">"), rep_fieldnum, rep_fieldnum, rep_fieldnum);
+
+ // Packed repeated.
+ assert_successful_parse(
+ cat( tag(rep_fieldnum, UPB_WIRE_TYPE_DELIMITED),
+ delim(cat( enc33, enc66 )) ),
+ LINE("<")
+ LINE("%u:[")
+ LINE(" %u:33")
+ LINE(" %u:66")
+ LINE("]")
+ LINE(">"), rep_fieldnum, rep_fieldnum, rep_fieldnum);
+}
+
+void test_valid_data_for_signed_type(upb_descriptortype_t type,
+ const string& enc33, const string& enc66) {
+ uint32_t fieldnum = type;
+ uint32_t rep_fieldnum = rep_fn(type);
+ int wire_type = upb_decoder_types[type].native_wire_type;
+
+ // Non-repeated
+ assert_successful_parse(
+ cat( tag(fieldnum, wire_type), enc33,
+ tag(fieldnum, wire_type), enc66 ),
+ LINE("<")
+ LINE("%u:33")
+ LINE("%u:-66")
+ LINE(">"), fieldnum, fieldnum);
+
+ // Non-packed repeated.
+ assert_successful_parse(
+ cat( tag(rep_fieldnum, wire_type), enc33,
+ tag(rep_fieldnum, wire_type), enc66 ),
+ LINE("<")
+ LINE("%u:[")
+ LINE(" %u:33")
+ LINE(" %u:-66")
+ LINE("]")
+ LINE(">"), rep_fieldnum, rep_fieldnum, rep_fieldnum);
+
+ // Packed repeated.
+ assert_successful_parse(
+ cat( tag(rep_fieldnum, UPB_WIRE_TYPE_DELIMITED),
+ delim(cat( enc33, enc66 )) ),
+ LINE("<")
+ LINE("%u:[")
+ LINE(" %u:33")
+ LINE(" %u:-66")
+ LINE("]")
+ LINE(">"), rep_fieldnum, rep_fieldnum, rep_fieldnum);
+}
+
+// Test that invalid protobufs are properly detected (without crashing) and
+// have an error reported. Field numbers match registered handlers above.
+void test_invalid() {
+ test_premature_eof_for_type(UPB_DESCRIPTOR_TYPE_DOUBLE);
+ test_premature_eof_for_type(UPB_DESCRIPTOR_TYPE_FLOAT);
+ test_premature_eof_for_type(UPB_DESCRIPTOR_TYPE_INT64);
+ test_premature_eof_for_type(UPB_DESCRIPTOR_TYPE_UINT64);
+ test_premature_eof_for_type(UPB_DESCRIPTOR_TYPE_INT32);
+ test_premature_eof_for_type(UPB_DESCRIPTOR_TYPE_FIXED64);
+ test_premature_eof_for_type(UPB_DESCRIPTOR_TYPE_FIXED32);
+ test_premature_eof_for_type(UPB_DESCRIPTOR_TYPE_BOOL);
+ test_premature_eof_for_type(UPB_DESCRIPTOR_TYPE_STRING);
+ test_premature_eof_for_type(UPB_DESCRIPTOR_TYPE_BYTES);
+ test_premature_eof_for_type(UPB_DESCRIPTOR_TYPE_UINT32);
+ test_premature_eof_for_type(UPB_DESCRIPTOR_TYPE_ENUM);
+ test_premature_eof_for_type(UPB_DESCRIPTOR_TYPE_SFIXED32);
+ test_premature_eof_for_type(UPB_DESCRIPTOR_TYPE_SFIXED64);
+ test_premature_eof_for_type(UPB_DESCRIPTOR_TYPE_SINT32);
+ test_premature_eof_for_type(UPB_DESCRIPTOR_TYPE_SINT64);
+
+ // EOF inside a tag's varint.
+ assert_does_not_parse_at_eof( string("\x80") );
+
+ // EOF inside a known group.
+ // TODO(haberman): add group to decoder test schema.
+ //assert_does_not_parse_at_eof( tag(4, UPB_WIRE_TYPE_START_GROUP) );
+
+ // EOF inside an unknown group.
+ assert_does_not_parse_at_eof( tag(UNKNOWN_FIELD, UPB_WIRE_TYPE_START_GROUP) );
+
+ // End group that we are not currently in.
+ assert_does_not_parse( tag(4, UPB_WIRE_TYPE_END_GROUP) );
+
+ // Field number is 0.
+ assert_does_not_parse(
+ cat( tag(0, UPB_WIRE_TYPE_DELIMITED), varint(0) ));
+ // The previous test alone did not catch this particular pattern which could
+ // corrupt the internal state.
+ assert_does_not_parse(
+ cat( tag(0, UPB_WIRE_TYPE_64BIT), uint64(0) ));
+
+ // Field number is too large.
+ assert_does_not_parse(
+ cat( tag(UPB_MAX_FIELDNUMBER + 1, UPB_WIRE_TYPE_DELIMITED),
+ varint(0) ));
+
+ // Known group inside a submessage has ENDGROUP tag AFTER submessage end.
+ assert_does_not_parse(
+ cat ( submsg(UPB_DESCRIPTOR_TYPE_MESSAGE,
+ tag(UPB_DESCRIPTOR_TYPE_GROUP, UPB_WIRE_TYPE_START_GROUP)),
+ tag(UPB_DESCRIPTOR_TYPE_GROUP, UPB_WIRE_TYPE_END_GROUP)));
+
+ // Unknown string extends past enclosing submessage.
+ assert_does_not_parse(
+ cat (badlen_submsg(-1, UPB_DESCRIPTOR_TYPE_MESSAGE,
+ submsg(12345, string(" "))),
+ submsg(UPB_DESCRIPTOR_TYPE_MESSAGE, string(" "))));
+
+ // Unknown fixed-length field extends past enclosing submessage.
+ assert_does_not_parse(
+ cat (badlen_submsg(-1, UPB_DESCRIPTOR_TYPE_MESSAGE,
+ cat( tag(12345, UPB_WIRE_TYPE_64BIT), uint64(0))),
+ submsg(UPB_DESCRIPTOR_TYPE_MESSAGE, string(" "))));
+
+ // Test exceeding the resource limit of stack depth.
+ if (test_mode != NO_HANDLERS) {
+ string buf;
+ for (int i = 0; i <= MAX_NESTING; i++) {
+ buf.assign(submsg(UPB_DESCRIPTOR_TYPE_MESSAGE, buf));
+ }
+ assert_does_not_parse(buf);
+ }
+}
+
+void test_valid() {
+ // Empty protobuf.
+ assert_successful_parse(string(""), "<\n>\n");
+
+ // Empty protobuf where we never call PutString between
+ // StartString/EndString.
+
+ // Randomly generated hash for this test, hope it doesn't conflict with others
+ // by chance.
+ const uint32_t emptyhash = 0x5709be8e;
+ if (!filter_hash || filter_hash == testhash) {
+ testhash = emptyhash;
+ upb::Status status;
+ upb::Arena arena;
+ upb::Sink sink(global_handlers, &closures[0]);
+ upb::pb::DecoderPtr decoder =
+ CreateDecoder(&arena, global_method, sink, &status);
+ output.clear();
+ bool ok = upb::PutBuffer(std::string(), decoder.input());
+ ASSERT(ok);
+ ASSERT(status.ok());
+ if (test_mode == ALL_HANDLERS) {
+ ASSERT(output == string("<\n>\n"));
+ }
+ }
+
+ test_valid_data_for_signed_type(UPB_DESCRIPTOR_TYPE_DOUBLE,
+ dbl(33),
+ dbl(-66));
+ test_valid_data_for_signed_type(UPB_DESCRIPTOR_TYPE_FLOAT, flt(33), flt(-66));
+ test_valid_data_for_signed_type(UPB_DESCRIPTOR_TYPE_INT64,
+ varint(33),
+ varint(-66));
+ test_valid_data_for_signed_type(UPB_DESCRIPTOR_TYPE_INT32,
+ varint(33),
+ varint(-66));
+ test_valid_data_for_signed_type(UPB_DESCRIPTOR_TYPE_ENUM,
+ varint(33),
+ varint(-66));
+ test_valid_data_for_signed_type(UPB_DESCRIPTOR_TYPE_SFIXED32,
+ uint32(33),
+ uint32(-66));
+ test_valid_data_for_signed_type(UPB_DESCRIPTOR_TYPE_SFIXED64,
+ uint64(33),
+ uint64(-66));
+ test_valid_data_for_signed_type(UPB_DESCRIPTOR_TYPE_SINT32,
+ zz32(33),
+ zz32(-66));
+ test_valid_data_for_signed_type(UPB_DESCRIPTOR_TYPE_SINT64,
+ zz64(33),
+ zz64(-66));
+
+ test_valid_data_for_type(UPB_DESCRIPTOR_TYPE_UINT64, varint(33), varint(66));
+ test_valid_data_for_type(UPB_DESCRIPTOR_TYPE_UINT32, varint(33), varint(66));
+ test_valid_data_for_type(UPB_DESCRIPTOR_TYPE_FIXED64, uint64(33), uint64(66));
+ test_valid_data_for_type(UPB_DESCRIPTOR_TYPE_FIXED32, uint32(33), uint32(66));
+
+ // Unknown fields.
+ int int32_type = UPB_DESCRIPTOR_TYPE_INT32;
+ int msg_type = UPB_DESCRIPTOR_TYPE_MESSAGE;
+ assert_successful_parse(
+ cat( tag(12345, UPB_WIRE_TYPE_VARINT), varint(2345678) ),
+ "<\n>\n");
+ assert_successful_parse(
+ cat( tag(12345, UPB_WIRE_TYPE_32BIT), uint32(2345678) ),
+ "<\n>\n");
+ assert_successful_parse(
+ cat( tag(12345, UPB_WIRE_TYPE_64BIT), uint64(2345678) ),
+ "<\n>\n");
+ assert_successful_parse(
+ submsg(12345, string(" ")),
+ "<\n>\n");
+
+ // Unknown field inside a known submessage.
+ assert_successful_parse(
+ submsg(UPB_DESCRIPTOR_TYPE_MESSAGE, submsg(12345, string(" "))),
+ LINE("<")
+ LINE("%u:{")
+ LINE(" <")
+ LINE(" >")
+ LINE("}")
+ LINE(">"), UPB_DESCRIPTOR_TYPE_MESSAGE);
+
+ assert_successful_parse(
+ cat (submsg(UPB_DESCRIPTOR_TYPE_MESSAGE, submsg(12345, string(" "))),
+ tag(UPB_DESCRIPTOR_TYPE_INT32, UPB_WIRE_TYPE_VARINT),
+ varint(5)),
+ LINE("<")
+ LINE("%u:{")
+ LINE(" <")
+ LINE(" >")
+ LINE("}")
+ LINE("%u:5")
+ LINE(">"), UPB_DESCRIPTOR_TYPE_MESSAGE, UPB_DESCRIPTOR_TYPE_INT32);
+
+ // This triggered a previous bug in the decoder.
+ assert_successful_parse(
+ cat( tag(UPB_DESCRIPTOR_TYPE_SFIXED32, UPB_WIRE_TYPE_VARINT),
+ varint(0) ),
+ "<\n>\n");
+
+ assert_successful_parse(
+ cat(
+ submsg(UPB_DESCRIPTOR_TYPE_MESSAGE,
+ submsg(UPB_DESCRIPTOR_TYPE_MESSAGE,
+ cat( tag(int32_type, UPB_WIRE_TYPE_VARINT), varint(2345678),
+ tag(12345, UPB_WIRE_TYPE_VARINT), varint(2345678) ))),
+ tag(int32_type, UPB_WIRE_TYPE_VARINT), varint(22222)),
+ LINE("<")
+ LINE("%u:{")
+ LINE(" <")
+ LINE(" %u:{")
+ LINE(" <")
+ LINE(" %u:2345678")
+ LINE(" >")
+ LINE(" }")
+ LINE(" >")
+ LINE("}")
+ LINE("%u:22222")
+ LINE(">"), msg_type, msg_type, int32_type, int32_type);
+
+ assert_successful_parse(
+ cat( tag(UPB_DESCRIPTOR_TYPE_INT32, UPB_WIRE_TYPE_VARINT), varint(1),
+ tag(12345, UPB_WIRE_TYPE_VARINT), varint(2345678) ),
+ LINE("<")
+ LINE("%u:1")
+ LINE(">"), UPB_DESCRIPTOR_TYPE_INT32);
+
+ // String inside submsg.
+ uint32_t msg_fn = UPB_DESCRIPTOR_TYPE_MESSAGE;
+ assert_successful_parse(
+ submsg(msg_fn,
+ cat ( tag(UPB_DESCRIPTOR_TYPE_STRING, UPB_WIRE_TYPE_DELIMITED),
+ delim(string("abcde"))
+ )
+ ),
+ LINE("<")
+ LINE("%u:{")
+ LINE(" <")
+ LINE(" %u:(5)\"abcde")
+ LINE(" %u:\"")
+ LINE(" >")
+ LINE("}")
+ LINE(">"), msg_fn, UPB_DESCRIPTOR_TYPE_STRING,
+ UPB_DESCRIPTOR_TYPE_STRING);
+
+ // Test implicit startseq/endseq.
+ uint32_t repfl_fn = rep_fn(UPB_DESCRIPTOR_TYPE_FLOAT);
+ uint32_t repdb_fn = rep_fn(UPB_DESCRIPTOR_TYPE_DOUBLE);
+ assert_successful_parse(
+ cat( tag(repfl_fn, UPB_WIRE_TYPE_32BIT), flt(33),
+ tag(repdb_fn, UPB_WIRE_TYPE_64BIT), dbl(66) ),
+ LINE("<")
+ LINE("%u:[")
+ LINE(" %u:33")
+ LINE("]")
+ LINE("%u:[")
+ LINE(" %u:66")
+ LINE("]")
+ LINE(">"), repfl_fn, repfl_fn, repdb_fn, repdb_fn);
+
+ // Submessage tests.
+ assert_successful_parse(
+ submsg(msg_fn, submsg(msg_fn, submsg(msg_fn, string()))),
+ LINE("<")
+ LINE("%u:{")
+ LINE(" <")
+ LINE(" %u:{")
+ LINE(" <")
+ LINE(" %u:{")
+ LINE(" <")
+ LINE(" >")
+ LINE(" }")
+ LINE(" >")
+ LINE(" }")
+ LINE(" >")
+ LINE("}")
+ LINE(">"), msg_fn, msg_fn, msg_fn);
+
+ uint32_t repm_fn = rep_fn(UPB_DESCRIPTOR_TYPE_MESSAGE);
+ assert_successful_parse(
+ submsg(repm_fn, submsg(repm_fn, string())),
+ LINE("<")
+ LINE("%u:[")
+ LINE(" %u:{")
+ LINE(" <")
+ LINE(" %u:[")
+ LINE(" %u:{")
+ LINE(" <")
+ LINE(" >")
+ LINE(" }")
+ LINE(" ]")
+ LINE(" >")
+ LINE(" }")
+ LINE("]")
+ LINE(">"), repm_fn, repm_fn, repm_fn, repm_fn);
+
+ // Test unknown group.
+ uint32_t unknown_group_fn = 12321;
+ assert_successful_parse(
+ cat( tag(unknown_group_fn, UPB_WIRE_TYPE_START_GROUP),
+ tag(unknown_group_fn, UPB_WIRE_TYPE_END_GROUP) ),
+ LINE("<")
+ LINE(">")
+ );
+
+ // Test some unknown fields inside an unknown group.
+ const string unknown_group_with_data =
+ cat(
+ tag(unknown_group_fn, UPB_WIRE_TYPE_START_GROUP),
+ tag(12345, UPB_WIRE_TYPE_VARINT), varint(2345678),
+ tag(123456789, UPB_WIRE_TYPE_32BIT), uint32(2345678),
+ tag(123477, UPB_WIRE_TYPE_64BIT), uint64(2345678),
+ tag(123, UPB_WIRE_TYPE_DELIMITED), varint(0),
+ tag(unknown_group_fn, UPB_WIRE_TYPE_END_GROUP)
+ );
+
+ // Nested unknown group with data.
+ assert_successful_parse(
+ cat(
+ tag(unknown_group_fn, UPB_WIRE_TYPE_START_GROUP),
+ unknown_group_with_data,
+ tag(unknown_group_fn, UPB_WIRE_TYPE_END_GROUP),
+ tag(UPB_DESCRIPTOR_TYPE_INT32, UPB_WIRE_TYPE_VARINT), varint(1)
+ ),
+ LINE("<")
+ LINE("%u:1")
+ LINE(">"),
+ UPB_DESCRIPTOR_TYPE_INT32
+ );
+
+ assert_successful_parse(
+ cat( tag(unknown_group_fn, UPB_WIRE_TYPE_START_GROUP),
+ tag(unknown_group_fn + 1, UPB_WIRE_TYPE_START_GROUP),
+ tag(unknown_group_fn + 1, UPB_WIRE_TYPE_END_GROUP),
+ tag(unknown_group_fn, UPB_WIRE_TYPE_END_GROUP) ),
+ LINE("<")
+ LINE(">")
+ );
+
+ // Staying within the stack limit should work properly.
+ string buf;
+ string textbuf;
+ int total = MAX_NESTING - 1;
+ for (int i = 0; i < total; i++) {
+ buf.assign(submsg(UPB_DESCRIPTOR_TYPE_MESSAGE, buf));
+ indentbuf(&textbuf, i);
+ textbuf.append("<\n");
+ indentbuf(&textbuf, i);
+ appendf(&textbuf, "%u:{\n", UPB_DESCRIPTOR_TYPE_MESSAGE);
+ }
+ indentbuf(&textbuf, total);
+ textbuf.append("<\n");
+ indentbuf(&textbuf, total);
+ textbuf.append(">\n");
+ for (int i = 0; i < total; i++) {
+ indentbuf(&textbuf, total - i - 1);
+ textbuf.append("}\n");
+ indentbuf(&textbuf, total - i - 1);
+ textbuf.append(">\n");
+ }
+ // Have to use run_decoder directly, because we are at max nesting and can't
+ // afford the extra nesting that assert_successful_parse() will do.
+ run_decoder(buf, &textbuf);
+}
+
+void empty_callback(const void *closure, upb::Handlers* h_ptr) {}
+
+void test_emptyhandlers(upb::SymbolTable* symtab) {
+ // Create an empty handlers to make sure that the decoder can handle empty
+ // messages.
+ HandlerRegisterData handlerdata;
+ handlerdata.mode = test_mode;
+
+ upb::HandlerCache handler_cache(empty_callback, &handlerdata);
+ upb::pb::CodeCache pb_code_cache(&handler_cache);
+
+ upb::MessageDefPtr md = upb::MessageDefPtr(Empty_getmsgdef(symtab->ptr()));
+ global_handlers = handler_cache.Get(md);
+ global_method = pb_code_cache.Get(md);
+
+ // TODO: also test the case where a message has fields, but the fields are
+ // submessage fields and have no handlers. This also results in a decoder
+ // method with no field-handling code.
+
+ // Ensure that the method can run with empty and non-empty input.
+ string test_unknown_field_msg =
+ cat(tag(1, UPB_WIRE_TYPE_VARINT), varint(42),
+ tag(2, UPB_WIRE_TYPE_DELIMITED), delim("My test data"));
+ const struct {
+ const char* data;
+ size_t length;
+ } testdata[] = {
+ { "", 0 },
+ { test_unknown_field_msg.data(), test_unknown_field_msg.size() },
+ { NULL, 0 },
+ };
+ for (int i = 0; testdata[i].data; i++) {
+ VerboseParserEnvironment env(filter_hash != 0);
+ upb::Sink sink(global_method.dest_handlers(), &closures[0]);
+ upb::pb::DecoderPtr decoder =
+ CreateDecoder(env.arena(), global_method, sink, env.status());
+ env.ResetBytesSink(decoder.input());
+ env.Reset(testdata[i].data, testdata[i].length, true, false);
+ ASSERT(env.Start());
+ ASSERT(env.ParseBuffer(-1));
+ ASSERT(env.End());
+ ASSERT(env.CheckConsistency());
+ }
+}
+
+void run_tests() {
+ HandlerRegisterData handlerdata;
+ handlerdata.mode = test_mode;
+
+ upb::SymbolTable symtab;
+ upb::HandlerCache handler_cache(callback, &handlerdata);
+ upb::pb::CodeCache pb_code_cache(&handler_cache);
+
+ upb::MessageDefPtr md(DecoderTest_getmsgdef(symtab.ptr()));
+ global_handlers = handler_cache.Get(md);
+ global_method = pb_code_cache.Get(md);
+ completed = 0;
+
+ test_invalid();
+ test_valid();
+
+ test_emptyhandlers(&symtab);
+}
+
+extern "C" {
+
+int run_tests(int argc, char *argv[]) {
+ if (argc > 1)
+ filter_hash = strtol(argv[1], NULL, 16);
+ for (int i = 0; i < MAX_NESTING; i++) {
+ closures[i] = i;
+ }
+
+ // Count tests.
+ count = &total;
+ total = 0;
+ test_mode = COUNT_ONLY;
+ run_tests();
+ count = &completed;
+
+ total *= 2; // NO_HANDLERS, ALL_HANDLERS.
+
+ test_mode = NO_HANDLERS;
+ run_tests();
+
+ test_mode = ALL_HANDLERS;
+ run_tests();
+
+ printf("All tests passed, %d assertions.\n", num_assertions);
+ return 0;
+}
+
+}
diff --git a/third_party/upb/tests/pb/test_decoder.proto b/third_party/upb/tests/pb/test_decoder.proto
new file mode 100644
index 00000000000..e9fa6ad32ce
--- /dev/null
+++ b/third_party/upb/tests/pb/test_decoder.proto
@@ -0,0 +1,128 @@
+
+syntax = "proto2";
+
+enum TestEnum {
+ FOO = 1;
+}
+
+message Empty {}
+
+message DecoderTest {
+ optional double f_double = 1;
+ optional float f_float = 2;
+ optional int64 f_int64 = 3;
+ optional uint64 f_uint64 = 4;
+ optional int32 f_int32 = 5;
+ optional fixed64 f_fixed64 = 6;
+ optional fixed32 f_fixed32 = 7;
+ optional bool f_bool = 8;
+ optional string f_string = 9;
+ optional DecoderTest f_message = 11;
+ optional bytes f_bytes = 12;
+ optional uint32 f_uint32 = 13;
+ optional TestEnum f_enum = 14;
+ optional sfixed32 f_sfixed32 = 15;
+ optional sfixed64 f_sfixed64 = 16;
+ optional sint32 f_sint32 = 17;
+ optional sint64 f_sint64 = 18;
+
+ optional string nop_field = 40;
+
+ repeated double r_double = 536869912;
+ repeated float r_float = 536869913;
+ repeated int64 r_int64 = 536869914;
+ repeated uint64 r_uint64 = 536869915;
+ repeated int32 r_int32 = 536869916;
+ repeated fixed64 r_fixed64 = 536869917;
+ repeated fixed32 r_fixed32 = 536869918;
+ repeated bool r_bool = 536869919;
+ repeated string r_string = 536869920;
+ repeated DecoderTest r_message = 536869922;
+ repeated bytes r_bytes = 536869923;
+ repeated uint32 r_uint32 = 536869924;
+ repeated TestEnum r_enum = 536869925;
+ repeated sfixed32 r_sfixed32 = 536869926;
+ repeated sfixed64 r_sfixed64 = 536869927;
+ repeated sint32 r_sint32 = 536869928;
+ repeated sint64 r_sint64 = 536869929;
+
+ optional group F_group = 10 {
+ optional double f_double = 1;
+ optional float f_float = 2;
+ optional int64 f_int64 = 3;
+ optional uint64 f_uint64 = 4;
+ optional int32 f_int32 = 5;
+ optional fixed64 f_fixed64 = 6;
+ optional fixed32 f_fixed32 = 7;
+ optional bool f_bool = 8;
+ optional string f_string = 9;
+ optional DecoderTest f_message = 11;
+ optional bytes f_bytes = 12;
+ optional uint32 f_uint32 = 13;
+ optional TestEnum f_enum = 14;
+ optional sfixed32 f_sfixed32 = 15;
+ optional sfixed64 f_sfixed64 = 16;
+ optional sint32 f_sint32 = 17;
+ optional sint64 f_sint64 = 18;
+
+ optional string nop_field = 40;
+
+ repeated double r_double = 536869912;
+ repeated float r_float = 536869913;
+ repeated int64 r_int64 = 536869914;
+ repeated uint64 r_uint64 = 536869915;
+ repeated int32 r_int32 = 536869916;
+ repeated fixed64 r_fixed64 = 536869917;
+ repeated fixed32 r_fixed32 = 536869918;
+ repeated bool r_bool = 536869919;
+ repeated string r_string = 536869920;
+ repeated DecoderTest r_message = 536869922;
+ repeated bytes r_bytes = 536869923;
+ repeated uint32 r_uint32 = 536869924;
+ repeated TestEnum r_enum = 536869925;
+ repeated sfixed32 r_sfixed32 = 536869926;
+ repeated sfixed64 r_sfixed64 = 536869927;
+ repeated sint32 r_sint32 = 536869928;
+ repeated sint64 r_sint64 = 536869929;
+ }
+
+ optional group R_group = 536869921 {
+ optional double f_double = 1;
+ optional float f_float = 2;
+ optional int64 f_int64 = 3;
+ optional uint64 f_uint64 = 4;
+ optional int32 f_int32 = 5;
+ optional fixed64 f_fixed64 = 6;
+ optional fixed32 f_fixed32 = 7;
+ optional bool f_bool = 8;
+ optional string f_string = 9;
+ optional DecoderTest f_message = 11;
+ optional bytes f_bytes = 12;
+ optional uint32 f_uint32 = 13;
+ optional TestEnum f_enum = 14;
+ optional sfixed32 f_sfixed32 = 15;
+ optional sfixed64 f_sfixed64 = 16;
+ optional sint32 f_sint32 = 17;
+ optional sint64 f_sint64 = 18;
+
+ optional string nop_field = 40;
+
+ repeated double r_double = 536869912;
+ repeated float r_float = 536869913;
+ repeated int64 r_int64 = 536869914;
+ repeated uint64 r_uint64 = 536869915;
+ repeated int32 r_int32 = 536869916;
+ repeated fixed64 r_fixed64 = 536869917;
+ repeated fixed32 r_fixed32 = 536869918;
+ repeated bool r_bool = 536869919;
+ repeated string r_string = 536869920;
+ repeated DecoderTest r_message = 536869922;
+ repeated bytes r_bytes = 536869923;
+ repeated uint32 r_uint32 = 536869924;
+ repeated TestEnum r_enum = 536869925;
+ repeated sfixed32 r_sfixed32 = 536869926;
+ repeated sfixed64 r_sfixed64 = 536869927;
+ repeated sint32 r_sint32 = 536869928;
+ repeated sint64 r_sint64 = 536869929;
+ }
+}
diff --git a/third_party/upb/tests/pb/test_encoder.cc b/third_party/upb/tests/pb/test_encoder.cc
new file mode 100644
index 00000000000..c6544beea57
--- /dev/null
+++ b/third_party/upb/tests/pb/test_encoder.cc
@@ -0,0 +1,48 @@
+
+#include "tests/test_util.h"
+#include "tests/upb_test.h"
+#include "upb/bindings/stdc++/string.h"
+#include "google/protobuf/descriptor.upb.h"
+#include "google/protobuf/descriptor.upbdefs.h"
+#include "upb/pb/decoder.h"
+#include "upb/pb/encoder.h"
+
+#include "upb/port_def.inc"
+#include
+
+void test_pb_roundtrip() {
+ std::string input(
+ google_protobuf_descriptor_proto_upbdefinit.descriptor.data,
+ google_protobuf_descriptor_proto_upbdefinit.descriptor.size);
+ std::cout << input.size() << "\n";
+ upb::SymbolTable symtab;
+ upb::HandlerCache encoder_cache(upb::pb::EncoderPtr::NewCache());
+ upb::pb::CodeCache decoder_cache(&encoder_cache);
+ upb::Arena arena;
+ upb::Status status;
+ upb::MessageDefPtr md(
+ google_protobuf_FileDescriptorProto_getmsgdef(symtab.ptr()));
+ ASSERT(md);
+ const upb::Handlers *encoder_handlers = encoder_cache.Get(md);
+ ASSERT(encoder_handlers);
+ const upb::pb::DecoderMethodPtr method = decoder_cache.Get(md);
+
+ std::string output;
+ upb::StringSink string_sink(&output);
+ upb::pb::EncoderPtr encoder =
+ upb::pb::EncoderPtr::Create(&arena, encoder_handlers, string_sink.input());
+ upb::pb::DecoderPtr decoder =
+ upb::pb::DecoderPtr::Create(&arena, method, encoder.input(), &status);
+ bool ok = upb::PutBuffer(input, decoder.input());
+ ASSERT(ok);
+ ASSERT(input == output);
+}
+
+extern "C" {
+int run_tests(int argc, char *argv[]) {
+ UPB_UNUSED(argc);
+ UPB_UNUSED(argv);
+ test_pb_roundtrip();
+ return 0;
+}
+}
diff --git a/third_party/upb/tests/pb/test_varint.c b/third_party/upb/tests/pb/test_varint.c
new file mode 100644
index 00000000000..95a04ab9b8d
--- /dev/null
+++ b/third_party/upb/tests/pb/test_varint.c
@@ -0,0 +1,117 @@
+
+#include
+#include "upb/pb/varint.int.h"
+#include "tests/upb_test.h"
+
+#include "upb/port_def.inc"
+
+/* Test that we can round-trip from int->varint->int. */
+static void test_varint_for_num(upb_decoderet (*decoder)(const char*),
+ uint64_t num) {
+ char buf[16];
+ size_t bytes;
+ upb_decoderet r;
+
+ memset(buf, 0xff, sizeof(buf));
+ bytes = upb_vencode64(num, buf);
+
+ if (num <= UINT32_MAX) {
+ uint64_t encoded = upb_vencode32(num);
+ char buf2[16];
+ upb_decoderet r;
+
+ memset(buf2, 0, sizeof(buf2));
+ memcpy(&buf2, &encoded, 8);
+#ifdef UPB_BIG_ENDIAN
+ char swap[8];
+ swap[0] = buf2[7];
+ swap[1] = buf2[6];
+ swap[2] = buf2[5];
+ swap[3] = buf2[4];
+ swap[4] = buf2[3];
+ swap[5] = buf2[2];
+ swap[6] = buf2[1];
+ swap[7] = buf2[0];
+ buf2[0] = swap[0];
+ buf2[1] = swap[1];
+ buf2[2] = swap[2];
+ buf2[3] = swap[3];
+ buf2[4] = swap[4];
+ buf2[5] = swap[5];
+ buf2[6] = swap[6];
+ buf2[7] = swap[7];
+#endif
+ r = decoder(buf2);
+ ASSERT(r.val == num);
+ ASSERT(r.p == buf2 + upb_value_size(encoded));
+ ASSERT(upb_zzenc_32(upb_zzdec_32(num)) == num);
+ }
+
+ r = decoder(buf);
+ ASSERT(r.val == num);
+ ASSERT(r.p == buf + bytes);
+ ASSERT(upb_zzenc_64(upb_zzdec_64(num)) == num);
+}
+
+static void test_varint_decoder(upb_decoderet (*decoder)(const char*)) {
+#define TEST(bytes, expected_val) {\
+ size_t n = sizeof(bytes) - 1; /* for NULL */ \
+ char buf[UPB_PB_VARINT_MAX_LEN]; \
+ upb_decoderet r; \
+ memset(buf, 0xff, sizeof(buf)); \
+ memcpy(buf, bytes, n); \
+ r = decoder(buf); \
+ ASSERT(r.val == expected_val); \
+ ASSERT(r.p == buf + n); \
+ }
+
+ uint64_t num;
+
+ char twelvebyte[16] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1};
+ const char *twelvebyte_buf = twelvebyte;
+ /* A varint that terminates before hitting the end of the provided buffer,
+ * but in too many bytes (11 instead of 10). */
+ upb_decoderet r = decoder(twelvebyte_buf);
+ ASSERT(r.p == NULL);
+
+ TEST("\x00", 0ULL);
+ TEST("\x01", 1ULL);
+ TEST("\x81\x14", 0xa01ULL);
+ TEST("\x81\x03", 0x181ULL);
+ TEST("\x81\x83\x07", 0x1c181ULL);
+ TEST("\x81\x83\x87\x0f", 0x1e1c181ULL);
+ TEST("\x81\x83\x87\x8f\x1f", 0x1f1e1c181ULL);
+ TEST("\x81\x83\x87\x8f\x9f\x3f", 0x1f9f1e1c181ULL);
+ TEST("\x81\x83\x87\x8f\x9f\xbf\x7f", 0x1fdf9f1e1c181ULL);
+ TEST("\x81\x83\x87\x8f\x9f\xbf\xff\x01", 0x3fdf9f1e1c181ULL);
+ TEST("\x81\x83\x87\x8f\x9f\xbf\xff\x81\x03", 0x303fdf9f1e1c181ULL);
+ TEST("\x81\x83\x87\x8f\x9f\xbf\xff\x81\x83\x07", 0x8303fdf9f1e1c181ULL);
+#undef TEST
+
+ for (num = 5; num * 1.5 < UINT64_MAX; num *= 1.5) {
+ test_varint_for_num(decoder, num);
+ }
+ test_varint_for_num(decoder, 0);
+}
+
+
+#define TEST_VARINT_DECODER(decoder) \
+ /* Create non-inline versions for convenient inspection of assembly language \
+ * output. */ \
+ upb_decoderet _upb_vdecode_ ## decoder(const char *p) { \
+ return upb_vdecode_ ## decoder(p); \
+ } \
+ void test_ ## decoder(void) { \
+ test_varint_decoder(&_upb_vdecode_ ## decoder); \
+ } \
+
+TEST_VARINT_DECODER(check2_branch32)
+TEST_VARINT_DECODER(check2_branch64)
+
+int run_tests(int argc, char *argv[]) {
+ UPB_UNUSED(argc);
+ UPB_UNUSED(argv);
+ test_check2_branch32();
+ test_check2_branch64();
+ return 0;
+}
diff --git a/third_party/upb/tests/test.proto b/third_party/upb/tests/test.proto
new file mode 100644
index 00000000000..e790cbf06d7
--- /dev/null
+++ b/third_party/upb/tests/test.proto
@@ -0,0 +1,68 @@
+
+// A series of messages with various kinds of cycles in them.
+// +-+---+ +---+ +---+
+// V | | V | V |
+// A -> B-+-> C -> D---+--->E---+
+// ^ |`---|--------^
+// +----------+----+ F
+
+syntax = "proto2";
+
+message A {
+ optional B b = 1;
+}
+
+message B {
+ optional B b = 1;
+ optional C c = 2;
+}
+
+message C {
+ optional A a = 1;
+ optional B b = 2;
+ optional D d = 3;
+ optional E e = 4;
+}
+
+message D {
+ optional A a = 1;
+ optional D d = 2;
+ optional E e = 3;
+}
+
+message E {
+ optional E e = 1;
+}
+
+message F {
+ optional E e = 1;
+}
+
+// A proto with a bunch of simple primitives.
+message SimplePrimitives {
+ optional fixed64 u64 = 1;
+ optional fixed32 u32 = 2;
+ optional double dbl = 3;
+ optional float flt = 5;
+ optional sint64 i64 = 6;
+ optional sint32 i32 = 7;
+ optional bool b = 8;
+ optional string str = 9;
+
+ oneof foo {
+ int32 oneof_int32 = 10;
+ string oneof_string = 11;
+ }
+
+ oneof bar {
+ int64 oneof_int64 = 13;
+ bytes oneof_bytes = 14;
+ }
+
+ message Nested {
+ oneof foo {
+ int32 oneof_int32 = 10;
+ string b = 11;
+ }
+ }
+}
diff --git a/third_party/upb/tests/test.proto.pb b/third_party/upb/tests/test.proto.pb
new file mode 100644
index 00000000000..a587fb18250
Binary files /dev/null and b/third_party/upb/tests/test.proto.pb differ
diff --git a/third_party/upb/tests/test_cpp.cc b/third_party/upb/tests/test_cpp.cc
new file mode 100644
index 00000000000..abbafdabc8f
--- /dev/null
+++ b/third_party/upb/tests/test_cpp.cc
@@ -0,0 +1,957 @@
+/*
+ *
+ * Tests for C++ wrappers.
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include "tests/test_cpp.upbdefs.h"
+#include "tests/upb_test.h"
+#include "upb/def.h"
+#include "upb/handlers.h"
+#include "upb/pb/decoder.h"
+#include "upb/pb/textprinter.h"
+#include "upb/port_def.inc"
+#include "upb/upb.h"
+
+template
+void AssertInsert(T* const container, const typename T::value_type& val) {
+ bool inserted = container->insert(val).second;
+ ASSERT(inserted);
+}
+
+//
+// Tests for registering and calling handlers in all their variants.
+// This test code is very repetitive because we have to declare each
+// handler function variant separately, and they all have different
+// signatures so it does not lend itself well to templates.
+//
+// We test three handler types:
+// StartMessage (no data params)
+// Int32 (1 data param (int32_t))
+// String Buf (2 data params (const char*, size_t))
+//
+// For each handler type we test all 8 handler variants:
+// (handler data?) x (function/method) x (returns {void, success})
+//
+// The one notable thing we don't test at the moment is
+// StartSequence/StartString handlers: these are different from StartMessage()
+// in that they return void* for the sub-closure. But this is exercised in
+// other tests.
+//
+
+static const int kExpectedHandlerData = 1232323;
+
+class StringBufTesterBase {
+ public:
+ static const int kFieldNumber = 3;
+
+ StringBufTesterBase() : seen_(false), handler_data_val_(0) {}
+
+ void CallAndVerify(upb::Sink sink, upb::FieldDefPtr f) {
+ upb_selector_t start;
+ ASSERT(upb_handlers_getselector(f.ptr(), UPB_HANDLER_STARTSTR, &start));
+ upb_selector_t str;
+ ASSERT(upb_handlers_getselector(f.ptr(), UPB_HANDLER_STRING, &str));
+
+ ASSERT(!seen_);
+ upb::Sink sub;
+ sink.StartMessage();
+ sink.StartString(start, 0, &sub);
+ size_t ret = sub.PutStringBuffer(str, &buf_, 5, &handle_);
+ ASSERT(seen_);
+ ASSERT(len_ == 5);
+ ASSERT(ret == 5);
+ ASSERT(handler_data_val_ == kExpectedHandlerData);
+ }
+
+ protected:
+ bool seen_;
+ int handler_data_val_;
+ size_t len_;
+ char buf_;
+ upb_bufhandle handle_;
+};
+
+// Test 8 combinations of:
+// (handler data?) x (buffer handle?) x (function/method)
+//
+// Then we add one test each for this variation: to prevent combinatorial
+// explosion of these tests we don't test the full 16 combinations, but
+// rely on our knowledge that the implementation processes the return wrapping
+// in a second separate and independent stage:
+//
+// (function/method)
+
+class StringBufTesterVoidMethodNoHandlerDataNoHandle
+ : public StringBufTesterBase {
+ public:
+ typedef StringBufTesterVoidMethodNoHandlerDataNoHandle ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
+ handler_data_val_ = kExpectedHandlerData;
+ }
+
+ private:
+ void Handler(const char *buf, size_t len) {
+ ASSERT(buf == &buf_);
+ seen_ = true;
+ len_ = len;
+ }
+};
+
+class StringBufTesterVoidMethodNoHandlerDataWithHandle
+ : public StringBufTesterBase {
+ public:
+ typedef StringBufTesterVoidMethodNoHandlerDataWithHandle ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
+ handler_data_val_ = kExpectedHandlerData;
+ }
+
+ private:
+ void Handler(const char *buf, size_t len, const upb_bufhandle* handle) {
+ ASSERT(buf == &buf_);
+ ASSERT(handle == &handle_);
+ seen_ = true;
+ len_ = len;
+ }
+};
+
+class StringBufTesterVoidMethodWithHandlerDataNoHandle
+ : public StringBufTesterBase {
+ public:
+ typedef StringBufTesterVoidMethodWithHandlerDataNoHandle ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStringHandler(
+ f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
+ }
+
+ private:
+ void Handler(const int* hd, const char *buf, size_t len) {
+ ASSERT(buf == &buf_);
+ handler_data_val_ = *hd;
+ seen_ = true;
+ len_ = len;
+ }
+};
+
+class StringBufTesterVoidMethodWithHandlerDataWithHandle
+ : public StringBufTesterBase {
+ public:
+ typedef StringBufTesterVoidMethodWithHandlerDataWithHandle ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStringHandler(
+ f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
+ }
+
+ private:
+ void Handler(const int* hd, const char* buf, size_t len,
+ const upb_bufhandle* handle) {
+ ASSERT(buf == &buf_);
+ ASSERT(handle == &handle_);
+ handler_data_val_ = *hd;
+ seen_ = true;
+ len_ = len;
+ }
+};
+
+class StringBufTesterVoidFunctionNoHandlerDataNoHandle
+ : public StringBufTesterBase {
+ public:
+ typedef StringBufTesterVoidFunctionNoHandlerDataNoHandle ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
+ handler_data_val_ = kExpectedHandlerData;
+ }
+
+ private:
+ static void Handler(ME* t, const char *buf, size_t len) {
+ ASSERT(buf == &t->buf_);
+ t->seen_ = true;
+ t->len_ = len;
+ }
+};
+
+class StringBufTesterVoidFunctionNoHandlerDataWithHandle
+ : public StringBufTesterBase {
+ public:
+ typedef StringBufTesterVoidFunctionNoHandlerDataWithHandle ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
+ handler_data_val_ = kExpectedHandlerData;
+ }
+
+ private:
+ static void Handler(ME* t, const char* buf, size_t len,
+ const upb_bufhandle* handle) {
+ ASSERT(buf == &t->buf_);
+ ASSERT(handle == &t->handle_);
+ t->seen_ = true;
+ t->len_ = len;
+ }
+};
+
+class StringBufTesterVoidFunctionWithHandlerDataNoHandle
+ : public StringBufTesterBase {
+ public:
+ typedef StringBufTesterVoidFunctionWithHandlerDataNoHandle ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStringHandler(
+ f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
+ }
+
+ private:
+ static void Handler(ME* t, const int* hd, const char *buf, size_t len) {
+ ASSERT(buf == &t->buf_);
+ t->handler_data_val_ = *hd;
+ t->seen_ = true;
+ t->len_ = len;
+ }
+};
+
+class StringBufTesterVoidFunctionWithHandlerDataWithHandle
+ : public StringBufTesterBase {
+ public:
+ typedef StringBufTesterVoidFunctionWithHandlerDataWithHandle ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStringHandler(
+ f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
+ }
+
+ private:
+ static void Handler(ME* t, const int* hd, const char* buf, size_t len,
+ const upb_bufhandle* handle) {
+ ASSERT(buf == &t->buf_);
+ ASSERT(handle == &t->handle_);
+ t->handler_data_val_ = *hd;
+ t->seen_ = true;
+ t->len_ = len;
+ }
+};
+
+class StringBufTesterSizeTMethodNoHandlerDataNoHandle
+ : public StringBufTesterBase {
+ public:
+ typedef StringBufTesterSizeTMethodNoHandlerDataNoHandle ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
+ handler_data_val_ = kExpectedHandlerData;
+ }
+
+ private:
+ size_t Handler(const char *buf, size_t len) {
+ ASSERT(buf == &buf_);
+ seen_ = true;
+ len_ = len;
+ return len;
+ }
+};
+
+class StringBufTesterBoolMethodNoHandlerDataNoHandle
+ : public StringBufTesterBase {
+ public:
+ typedef StringBufTesterBoolMethodNoHandlerDataNoHandle ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
+ handler_data_val_ = kExpectedHandlerData;
+ }
+
+ private:
+ bool Handler(const char *buf, size_t len) {
+ ASSERT(buf == &buf_);
+ seen_ = true;
+ len_ = len;
+ return true;
+ }
+};
+
+class StartMsgTesterBase {
+ public:
+ // We don't need the FieldDef it will create, but the test harness still
+ // requires that we provide one.
+ static const int kFieldNumber = 3;
+
+ StartMsgTesterBase() : seen_(false), handler_data_val_(0) {}
+
+ void CallAndVerify(upb::Sink sink, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(!seen_);
+ sink.StartMessage();
+ ASSERT(seen_);
+ ASSERT(handler_data_val_ == kExpectedHandlerData);
+ }
+
+ protected:
+ bool seen_;
+ int handler_data_val_;
+};
+
+// Test all 8 combinations of:
+// (handler data?) x (function/method) x (returns {void, bool})
+
+class StartMsgTesterVoidFunctionNoHandlerData : public StartMsgTesterBase {
+ public:
+ typedef StartMsgTesterVoidFunctionNoHandlerData ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStartMessageHandler(UpbMakeHandler(&Handler)));
+ handler_data_val_ = kExpectedHandlerData;
+ }
+
+ private:
+ //static void Handler(ME* t) {
+ static void Handler(ME* t) {
+ t->seen_ = true;
+ }
+};
+
+class StartMsgTesterBoolFunctionNoHandlerData : public StartMsgTesterBase {
+ public:
+ typedef StartMsgTesterBoolFunctionNoHandlerData ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStartMessageHandler(UpbMakeHandler(&Handler)));
+ handler_data_val_ = kExpectedHandlerData;
+ }
+
+ private:
+ static bool Handler(ME* t) {
+ t->seen_ = true;
+ return true;
+ }
+};
+
+class StartMsgTesterVoidMethodNoHandlerData : public StartMsgTesterBase {
+ public:
+ typedef StartMsgTesterVoidMethodNoHandlerData ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStartMessageHandler(UpbMakeHandler(&ME::Handler)));
+ handler_data_val_ = kExpectedHandlerData;
+ }
+
+ private:
+ void Handler() {
+ seen_ = true;
+ }
+};
+
+class StartMsgTesterBoolMethodNoHandlerData : public StartMsgTesterBase {
+ public:
+ typedef StartMsgTesterBoolMethodNoHandlerData ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStartMessageHandler(UpbMakeHandler(&ME::Handler)));
+ handler_data_val_ = kExpectedHandlerData;
+ }
+
+ private:
+ bool Handler() {
+ seen_ = true;
+ return true;
+ }
+};
+
+class StartMsgTesterVoidFunctionWithHandlerData : public StartMsgTesterBase {
+ public:
+ typedef StartMsgTesterVoidFunctionWithHandlerData ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStartMessageHandler(
+ UpbBind(&Handler, new int(kExpectedHandlerData))));
+ }
+
+ private:
+ static void Handler(ME* t, const int* hd) {
+ t->handler_data_val_ = *hd;
+ t->seen_ = true;
+ }
+};
+
+class StartMsgTesterBoolFunctionWithHandlerData : public StartMsgTesterBase {
+ public:
+ typedef StartMsgTesterBoolFunctionWithHandlerData ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStartMessageHandler(
+ UpbBind(&Handler, new int(kExpectedHandlerData))));
+ }
+
+ private:
+ static bool Handler(ME* t, const int* hd) {
+ t->handler_data_val_ = *hd;
+ t->seen_ = true;
+ return true;
+ }
+};
+
+class StartMsgTesterVoidMethodWithHandlerData : public StartMsgTesterBase {
+ public:
+ typedef StartMsgTesterVoidMethodWithHandlerData ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStartMessageHandler(
+ UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
+ }
+
+ private:
+ void Handler(const int* hd) {
+ handler_data_val_ = *hd;
+ seen_ = true;
+ }
+};
+
+class StartMsgTesterBoolMethodWithHandlerData : public StartMsgTesterBase {
+ public:
+ typedef StartMsgTesterBoolMethodWithHandlerData ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ UPB_UNUSED(f);
+ ASSERT(h.SetStartMessageHandler(
+ UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
+ }
+
+ private:
+ bool Handler(const int* hd) {
+ handler_data_val_ = *hd;
+ seen_ = true;
+ return true;
+ }
+};
+
+class Int32ValueTesterBase {
+ public:
+ static const int kFieldNumber = 1;
+
+ Int32ValueTesterBase() : seen_(false), val_(0), handler_data_val_(0) {}
+
+ void CallAndVerify(upb::Sink sink, upb::FieldDefPtr f) {
+ upb_selector_t s;
+ ASSERT(upb_handlers_getselector(f.ptr(), UPB_HANDLER_INT32, &s));
+
+ ASSERT(!seen_);
+ sink.PutInt32(s, 5);
+ ASSERT(seen_);
+ ASSERT(handler_data_val_ == kExpectedHandlerData);
+ ASSERT(val_ == 5);
+ }
+
+ protected:
+ bool seen_;
+ int32_t val_;
+ int handler_data_val_;
+};
+
+// Test all 8 combinations of:
+// (handler data?) x (function/method) x (returns {void, bool})
+
+class ValueTesterInt32VoidFunctionNoHandlerData
+ : public Int32ValueTesterBase {
+ public:
+ typedef ValueTesterInt32VoidFunctionNoHandlerData ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ ASSERT(h.SetInt32Handler(f, UpbMakeHandler(&Handler)));
+ handler_data_val_ = kExpectedHandlerData;
+ }
+
+ private:
+ static void Handler(ME* t, int32_t val) {
+ t->val_ = val;
+ t->seen_ = true;
+ }
+};
+
+class ValueTesterInt32BoolFunctionNoHandlerData
+ : public Int32ValueTesterBase {
+ public:
+ typedef ValueTesterInt32BoolFunctionNoHandlerData ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ ASSERT(h.SetInt32Handler(f, UpbMakeHandler(&Handler)));
+ handler_data_val_ = kExpectedHandlerData;
+ }
+
+ private:
+ static bool Handler(ME* t, int32_t val) {
+ t->val_ = val;
+ t->seen_ = true;
+ return true;
+ }
+};
+
+class ValueTesterInt32VoidMethodNoHandlerData : public Int32ValueTesterBase {
+ public:
+ typedef ValueTesterInt32VoidMethodNoHandlerData ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ ASSERT(h.SetInt32Handler(f, UpbMakeHandler(&ME::Handler)));
+ handler_data_val_ = kExpectedHandlerData;
+ }
+
+ private:
+ void Handler(int32_t val) {
+ val_ = val;
+ seen_ = true;
+ }
+};
+
+class ValueTesterInt32BoolMethodNoHandlerData : public Int32ValueTesterBase {
+ public:
+ typedef ValueTesterInt32BoolMethodNoHandlerData ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ ASSERT(h.SetInt32Handler(f, UpbMakeHandler(&ME::Handler)));
+ handler_data_val_ = kExpectedHandlerData;
+ }
+
+ private:
+ bool Handler(int32_t val) {
+ val_ = val;
+ seen_ = true;
+ return true;
+ }
+};
+
+class ValueTesterInt32VoidFunctionWithHandlerData
+ : public Int32ValueTesterBase {
+ public:
+ typedef ValueTesterInt32VoidFunctionWithHandlerData ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ ASSERT(h.SetInt32Handler(
+ f, UpbBind(&Handler, new int(kExpectedHandlerData))));
+ }
+
+ private:
+ static void Handler(ME* t, const int* hd, int32_t val) {
+ t->val_ = val;
+ t->handler_data_val_ = *hd;
+ t->seen_ = true;
+ }
+};
+
+class ValueTesterInt32BoolFunctionWithHandlerData
+ : public Int32ValueTesterBase {
+ public:
+ typedef ValueTesterInt32BoolFunctionWithHandlerData ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ ASSERT(h.SetInt32Handler(
+ f, UpbBind(&Handler, new int(kExpectedHandlerData))));
+ }
+
+ private:
+ static bool Handler(ME* t, const int* hd, int32_t val) {
+ t->val_ = val;
+ t->handler_data_val_ = *hd;
+ t->seen_ = true;
+ return true;
+ }
+};
+
+class ValueTesterInt32VoidMethodWithHandlerData : public Int32ValueTesterBase {
+ public:
+ typedef ValueTesterInt32VoidMethodWithHandlerData ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ ASSERT(h.SetInt32Handler(
+ f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
+ }
+
+ private:
+ void Handler(const int* hd, int32_t val) {
+ val_ = val;
+ handler_data_val_ = *hd;
+ seen_ = true;
+ }
+};
+
+class ValueTesterInt32BoolMethodWithHandlerData : public Int32ValueTesterBase {
+ public:
+ typedef ValueTesterInt32BoolMethodWithHandlerData ME;
+ void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
+ ASSERT(h.SetInt32Handler(
+ f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
+ }
+
+ private:
+ bool Handler(const int* hd, int32_t val) {
+ val_ = val;
+ handler_data_val_ = *hd;
+ seen_ = true;
+ return true;
+ }
+};
+
+template
+void RegisterHandlers(const void* closure, upb::Handlers* h_ptr) {
+ T* tester = const_cast(static_cast(closure));
+ upb::HandlersPtr h(h_ptr);
+ upb::FieldDefPtr f = h.message_def().FindFieldByNumber(T::kFieldNumber);
+ ASSERT(f);
+ tester->Register(h, f);
+}
+
+template
+void TestHandler() {
+ T tester;
+ upb::SymbolTable symtab;
+ upb::HandlerCache cache(&RegisterHandlers, &tester);
+ upb::MessageDefPtr md(upb_test_TestMessage_getmsgdef(symtab.ptr()));
+ ASSERT(md);
+ upb::FieldDefPtr f = md.FindFieldByNumber(T::kFieldNumber);
+ ASSERT(f);
+
+ const upb::Handlers* h = cache.Get(md);
+
+ upb::Sink sink(h, &tester);
+ tester.CallAndVerify(sink, f);
+}
+
+class T1 {};
+class T2 {};
+
+template
+void DoNothingHandler(C* closure) {
+ UPB_UNUSED(closure);
+}
+
+template
+void DoNothingInt32Handler(C* closure, int32_t val) {
+ UPB_UNUSED(closure);
+ UPB_UNUSED(val);
+}
+
+template
+class DoNothingStartHandler {
+ public:
+ // We wrap these functions inside of a class for a somewhat annoying reason.
+ // UpbMakeHandler() is a macro, so we can't say
+ // UpbMakeHandler(DoNothingStartHandler)
+ //
+ // because otherwise the preprocessor gets confused at the comma and tries to
+ // make it two macro arguments. The usual solution doesn't work either:
+ // UpbMakeHandler((DoNothingStartHandler))
+ //
+ // If we do that the macro expands correctly, but then it tries to pass that
+ // parenthesized expression as a template parameter, ie. Type<(F)>, which
+ // isn't legal C++ (Clang will compile it but complains with
+ // warning: address non-type template argument cannot be surrounded by
+ // parentheses
+ //
+ // This two-level thing allows us to effectively pass two template parameters,
+ // but without any commas:
+ // UpbMakeHandler(DoNothingStartHandler::Handler)
+ template
+ static R* Handler(C* closure) {
+ UPB_UNUSED(closure);
+ return NULL;
+ }
+
+ template
+ static R* String(C* closure, size_t size_len) {
+ UPB_UNUSED(closure);
+ UPB_UNUSED(size_len);
+ return NULL;
+ }
+};
+
+template
+void DoNothingStringBufHandler(C* closure, const char *buf, size_t len) {
+ UPB_UNUSED(closure);
+ UPB_UNUSED(buf);
+ UPB_UNUSED(len);
+}
+
+template
+void DoNothingEndMessageHandler(C* closure, upb_status *status) {
+ UPB_UNUSED(closure);
+ UPB_UNUSED(status);
+}
+
+void RegisterMismatchedTypes(const void* closure, upb::Handlers* h_ptr) {
+ upb::HandlersPtr h(h_ptr);
+
+ upb::MessageDefPtr md(h.message_def());
+ ASSERT(md);
+ upb::FieldDefPtr i32 = md.FindFieldByName("i32");
+ upb::FieldDefPtr r_i32 = md.FindFieldByName("r_i32");
+ upb::FieldDefPtr str = md.FindFieldByName("str");
+ upb::FieldDefPtr r_str = md.FindFieldByName("r_str");
+ upb::FieldDefPtr msg = md.FindFieldByName("msg");
+ upb::FieldDefPtr r_msg = md.FindFieldByName("r_msg");
+ ASSERT(i32);
+ ASSERT(r_i32);
+ ASSERT(str);
+ ASSERT(r_str);
+ ASSERT(msg);
+ ASSERT(r_msg);
+
+ // Establish T1 as the top-level closure type.
+ ASSERT(h.SetInt32Handler(i32, UpbMakeHandler(DoNothingInt32Handler)));
+
+ // Now any other attempt to set another handler with T2 as the top-level
+ // closure should fail. But setting these same handlers with T1 as the
+ // top-level closure will succeed.
+ ASSERT(!h.SetStartMessageHandler(UpbMakeHandler(DoNothingHandler)));
+ ASSERT(h.SetStartMessageHandler(UpbMakeHandler(DoNothingHandler)));
+
+ ASSERT(
+ !h.SetEndMessageHandler(UpbMakeHandler(DoNothingEndMessageHandler)));
+ ASSERT(
+ h.SetEndMessageHandler(UpbMakeHandler(DoNothingEndMessageHandler)));
+
+ ASSERT(!h.SetStartStringHandler(
+ str, UpbMakeHandler(DoNothingStartHandler::String)));
+ ASSERT(h.SetStartStringHandler(
+ str, UpbMakeHandler(DoNothingStartHandler::String)));
+
+ ASSERT(!h.SetEndStringHandler(str, UpbMakeHandler(DoNothingHandler)));
+ ASSERT(h.SetEndStringHandler(str, UpbMakeHandler(DoNothingHandler)));
+
+ ASSERT(!h.SetStartSubMessageHandler(
+ msg, UpbMakeHandler(DoNothingStartHandler::Handler)));
+ ASSERT(h.SetStartSubMessageHandler(
+ msg, UpbMakeHandler(DoNothingStartHandler::Handler)));
+
+ ASSERT(
+ !h.SetEndSubMessageHandler(msg, UpbMakeHandler(DoNothingHandler)));
+ ASSERT(
+ h.SetEndSubMessageHandler(msg, UpbMakeHandler(DoNothingHandler)));
+
+ ASSERT(!h.SetStartSequenceHandler(
+ r_i32, UpbMakeHandler(DoNothingStartHandler::Handler)));
+ ASSERT(h.SetStartSequenceHandler(
+ r_i32, UpbMakeHandler(DoNothingStartHandler::Handler)));
+
+ ASSERT(!h.SetEndSequenceHandler(
+ r_i32, UpbMakeHandler(DoNothingHandler)));
+ ASSERT(h.SetEndSequenceHandler(
+ r_i32, UpbMakeHandler(DoNothingHandler)));
+
+ ASSERT(!h.SetStartSequenceHandler(
+ r_msg, UpbMakeHandler(DoNothingStartHandler::Handler)));
+ ASSERT(h.SetStartSequenceHandler(
+ r_msg, UpbMakeHandler(DoNothingStartHandler::Handler)));
+
+ ASSERT(!h.SetEndSequenceHandler(
+ r_msg, UpbMakeHandler(DoNothingHandler)));
+ ASSERT(h.SetEndSequenceHandler(
+ r_msg, UpbMakeHandler(DoNothingHandler)));
+
+ ASSERT(!h.SetStartSequenceHandler(
+ r_str, UpbMakeHandler(DoNothingStartHandler::Handler)));
+ ASSERT(h.SetStartSequenceHandler(
+ r_str, UpbMakeHandler(DoNothingStartHandler::Handler)));
+
+ ASSERT(!h.SetEndSequenceHandler(
+ r_str, UpbMakeHandler(DoNothingHandler)));
+ ASSERT(h.SetEndSequenceHandler(
+ r_str, UpbMakeHandler(DoNothingHandler)));
+
+ // By setting T1 as the return type for the Start* handlers we have
+ // established T1 as the type of the sequence and string frames.
+ // Setting callbacks that use T2 should fail, but T1 should succeed.
+ ASSERT(
+ !h.SetStringHandler(str, UpbMakeHandler(DoNothingStringBufHandler)));
+ ASSERT(
+ h.SetStringHandler(str, UpbMakeHandler(DoNothingStringBufHandler)));
+
+ ASSERT(!h.SetInt32Handler(r_i32, UpbMakeHandler(DoNothingInt32Handler)));
+ ASSERT(h.SetInt32Handler(r_i32, UpbMakeHandler(DoNothingInt32Handler)));
+
+ ASSERT(!h.SetStartSubMessageHandler(
+ r_msg, UpbMakeHandler(DoNothingStartHandler::Handler)));
+ ASSERT(h.SetStartSubMessageHandler(
+ r_msg, UpbMakeHandler(DoNothingStartHandler::Handler)));
+
+ ASSERT(!h.SetEndSubMessageHandler(r_msg,
+ UpbMakeHandler(DoNothingHandler)));
+ ASSERT(h.SetEndSubMessageHandler(r_msg,
+ UpbMakeHandler(DoNothingHandler)));
+
+ ASSERT(!h.SetStartStringHandler(
+ r_str, UpbMakeHandler(DoNothingStartHandler::String)));
+ ASSERT(h.SetStartStringHandler(
+ r_str, UpbMakeHandler(DoNothingStartHandler::String)));
+
+ ASSERT(
+ !h.SetEndStringHandler(r_str, UpbMakeHandler(DoNothingHandler)));
+ ASSERT(h.SetEndStringHandler(r_str, UpbMakeHandler(DoNothingHandler)));
+
+ ASSERT(!h.SetStringHandler(r_str,
+ UpbMakeHandler(DoNothingStringBufHandler)));
+ ASSERT(h.SetStringHandler(r_str,
+ UpbMakeHandler(DoNothingStringBufHandler)));
+}
+
+void RegisterMismatchedTypes2(const void* closure, upb::Handlers* h_ptr) {
+ upb::HandlersPtr h(h_ptr);
+
+ upb::MessageDefPtr md(h.message_def());
+ ASSERT(md);
+ upb::FieldDefPtr i32 = md.FindFieldByName("i32");
+ upb::FieldDefPtr r_i32 = md.FindFieldByName("r_i32");
+ upb::FieldDefPtr str = md.FindFieldByName("str");
+ upb::FieldDefPtr r_str = md.FindFieldByName("r_str");
+ upb::FieldDefPtr msg = md.FindFieldByName("msg");
+ upb::FieldDefPtr r_msg = md.FindFieldByName("r_msg");
+ ASSERT(i32);
+ ASSERT(r_i32);
+ ASSERT(str);
+ ASSERT(r_str);
+ ASSERT(msg);
+ ASSERT(r_msg);
+
+ // For our second test we do the same in reverse. We directly set the type of
+ // the frame and then observe failures at registering a Start* handler that
+ // returns a different type.
+
+ // First establish the type of a sequence frame directly.
+ ASSERT(h.SetInt32Handler(r_i32, UpbMakeHandler(DoNothingInt32Handler)));
+
+ // Now setting a StartSequence callback that returns a different type should
+ // fail.
+ ASSERT(!h.SetStartSequenceHandler(
+ r_i32, UpbMakeHandler(DoNothingStartHandler::Handler)));
+ ASSERT(h.SetStartSequenceHandler(
+ r_i32, UpbMakeHandler(DoNothingStartHandler::Handler)));
+
+ // Establish a string frame directly.
+ ASSERT(h.SetStringHandler(r_str,
+ UpbMakeHandler(DoNothingStringBufHandler)));
+
+ // Fail setting a StartString callback that returns a different type.
+ ASSERT(!h.SetStartStringHandler(
+ r_str, UpbMakeHandler(DoNothingStartHandler::String)));
+ ASSERT(h.SetStartStringHandler(
+ r_str, UpbMakeHandler(DoNothingStartHandler::String)));
+
+ // The previous established T1 as the frame for the r_str sequence.
+ ASSERT(!h.SetStartSequenceHandler(
+ r_str, UpbMakeHandler(DoNothingStartHandler::Handler)));
+ ASSERT(h.SetStartSequenceHandler(
+ r_str, UpbMakeHandler(DoNothingStartHandler::Handler)));
+}
+
+void TestMismatchedTypes() {
+ // First create a schema for our test.
+ upb::SymbolTable symtab;
+ upb::HandlerCache handler_cache(&RegisterMismatchedTypes, nullptr);
+ upb::HandlerCache handler_cache2(&RegisterMismatchedTypes2, nullptr);
+ const upb::MessageDefPtr md(upb_test_TestMessage_getmsgdef(symtab.ptr()));
+
+ // Now test the type-checking in handler registration.
+ handler_cache.Get(md);
+ handler_cache2.Get(md);
+}
+
+class IntIncrementer {
+ public:
+ explicit IntIncrementer(int* x) : x_(x) { (*x_)++; }
+ ~IntIncrementer() { (*x_)--; }
+
+ static void Handler(void* closure, const IntIncrementer* incrementer,
+ int32_t x) {
+ UPB_UNUSED(closure);
+ UPB_UNUSED(incrementer);
+ UPB_UNUSED(x);
+ }
+
+ private:
+ int* x_;
+};
+
+void RegisterIncrementor(const void* closure, upb::Handlers* h_ptr) {
+ const int* x = static_cast(closure);
+ upb::HandlersPtr h(h_ptr);
+ upb::FieldDefPtr f = h.message_def().FindFieldByName("i32");
+ h.SetInt32Handler(f, UpbBind(&IntIncrementer::Handler,
+ new IntIncrementer(const_cast(x))));
+}
+
+void TestHandlerDataDestruction() {
+ int x = 0;
+
+ {
+ upb::SymbolTable symtab;
+ upb::HandlerCache cache(&RegisterIncrementor, &x);
+ upb::MessageDefPtr md(upb_test_TestMessage_getmsgdef(symtab.ptr()));
+ cache.Get(md);
+ ASSERT(x == 1);
+ }
+
+ ASSERT(x == 0);
+}
+
+void TestIteration() {
+ upb::SymbolTable symtab;
+ upb::MessageDefPtr md(upb_test_TestMessage_getmsgdef(symtab.ptr()));
+
+ // Test range-based for on both fields and oneofs (with the iterator adaptor).
+ int field_count = 0;
+ for (auto field : md.fields()) {
+ UPB_UNUSED(field);
+ field_count++;
+ }
+ ASSERT(field_count == md.field_count());
+
+ int oneof_count = 0;
+ for (auto oneof : md.oneofs()) {
+ UPB_UNUSED(oneof);
+ oneof_count++;
+ }
+ ASSERT(oneof_count == md.oneof_count());
+}
+
+extern "C" {
+
+int run_tests(int argc, char *argv[]) {
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+ TestHandler();
+
+ TestMismatchedTypes();
+
+ TestHandlerDataDestruction();
+ TestIteration();
+
+ return 0;
+}
+
+}
diff --git a/third_party/upb/tests/test_cpp.proto b/third_party/upb/tests/test_cpp.proto
new file mode 100644
index 00000000000..f890350ece1
--- /dev/null
+++ b/third_party/upb/tests/test_cpp.proto
@@ -0,0 +1,12 @@
+syntax = "proto2";
+
+package upb.test;
+
+message TestMessage {
+ optional int32 i32 = 1;
+ repeated int32 r_i32 = 2;
+ optional string str = 3;
+ repeated string r_str = 4;
+ optional TestMessage msg = 5;
+ repeated TestMessage r_msg = 6;
+}
diff --git a/third_party/upb/tests/test_table.cc b/third_party/upb/tests/test_table.cc
new file mode 100644
index 00000000000..063eb68cee6
--- /dev/null
+++ b/third_party/upb/tests/test_table.cc
@@ -0,0 +1,679 @@
+/*
+ *
+ * Tests for upb_table.
+ */
+
+#include
+#include
+#include
+#include
+#include